On Sat, 14 Jul 2007 03:51:06 +0900, Mike Kasick <mkasick-rt / club.cc.cmu.edu> wrote:
> I'm working on a project where oversynchronization may actually be costly

Have you measured to see whether this is actually the case?

> I'm curious about how much I can actually do with core datastructures
> before running into thread safety issues.

Not much at all.  Reading a data structure from multiple threads is
fine as long as nothing ever writes to it once it becomes shared, and
as long as each thread besides the one creating/initializing the object
obtained its original reference to the data structure through synchronized
means.

> I've seen the issue of thread safety come up a couple times on the list
> before but I've not been able to find concrete answers as to what exactly
> is safe.

Giving up synchronization means that (depending on the particulars of the
Ruby implementation) you lose a lot of important guarantees like memory
operations being visible in a logical order.  It isn't so much a question
of what is and isn't safe: once you drop synchronization, all bets are off.

(Generally a Ruby implementation will try to make sure you can't crash
the interpreter, but beyond that you're on your own.)

The best way to get good threaded performance in a Ruby program is:

 1. minimize the amount of synchronization required

    a. as much as possible, try to only share "immutable" objects between
       threads

    b. make thread-local copies of things

    c. let one thread have responsibility for an object at a time,
       passing objects between threads via a synchronized communication
       mechanism like Queue

 2. load fastthread after thread.rb (but rescue LoadError if it's not
    available)

If you'd like to describe what you're doing with the shared Hash, I may
also be able to give more specific advice.

> A semi-related question:  Are there readers/writers locks for Ruby?  I've
> not seen one.

There is sync.rb in stdlib, but I wouldn't recommend using it because the
implementation is very poor.

-mental