When I’ve written multithreaded code in Ruby in the past I’ve been quite
diligent about synchronizing access to shared resources. However, now
I’m
working on a project where oversynchronization may actually be costly
and
I’m curious about how much I can actually do with core datastructures
before running into thread safety issues.
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.
Thus, a few questions:
-
Will Hash#[] always return either a previously assigned value, or
the
default value, despite interleaved calls to Hash#[]= and
Hash#delete?Or is it possible for Hash#[] in such a scenario to result in a wild
pointer access that would raise an exception or worse? -
Will interleaved calls to Hash#[]= do something sensible? That is,
when all interleaved calls are finished, will a lookup always return
one of the previously assigned values (even if it’s not the most
“recent”)? -
Can something “bad” happen when a hash is modified during execution
of
Hash#each? I understand that such a call may yield elements that
were added since the start of its execution, or may not yield
elements
that were delete since the start of its execution. But, at least,
will
all key/value pairs be yielded that weren’t modified during
execution?Will each pair be yielded only once? I’m thinking a rehash during
#each
could result in disaster. -
In general, can the lack of Ruby-level synchronization actually
corrupt
a datastructure in some really unfortunate way? For example, could
interfering mutations to middle elements of an array accidentally
lop
off the entire end of an array? -
Does the answer to any of the above change for ruby 1.9?
Basically, in short, I’m willing to give up synchronized access to data
structures for trivial operations (i.e., lookups) where the result is
only
valid for an infinitessimally short peiord anyways, so long as I know
that
it won’t result in wild application behavior like exceptions or a
segfault.
A semi-related question: Are there readers/writers locks for Ruby?
I’ve
not seen one.
Thanks!