SPUG: threading, atomicity and safeness
Fred Morris
m3047 at inwa.net
Mon Apr 28 14:47:28 PDT 2008
"Atomicity" refers to an operation which simply cannot and will not be
interrupted. For instance a single machine instruction executing on a single
CPU is generally considered atomic (although the VAX had certain machine
instructions which *were* interruptible, and had certain others which had an
"interlocked" form which asserted a halt against other CPUs on the bus IIRC).
So no thread can possibly be interrupted in the middle of one of these
operations.
"Safeness" refers to something which happens up a level or two, when compilers
optimize instructions out of memory and into registers... hence it is not
safe for multiple threads to attempt to modify the "same" variable (because
each has a different register copy)... and therefore compilers end up with
"unsafe" pragmas and flags to keep certain variables from being optimized
that way.
This gets a little inside-out or at least the level of abstraction is more or
less levelled out, but I find myself wondering some of these same things
about Perl (and Python) and I don't find any discussion of these issues.
Who cares? Well:
* Atomicity means you can modify a value (on the VAX this was not just store,
but increment and add... and a few other oddball things) without throwing a
lock around it. Ok, maybe this "just isn't safe" if you've never taken a dive
beneath the flotsam generated by compilers and so you just don't go there,
but if you've ever written assembler maybe you've skipped a couple
locking/semaphore library calls with complete impunity... besides, it's
faster (that's a fact).
* Safeness means that two threads are actually assured that they are in fact
reading (or I suppose updating, but if reading isn't safe then who cares) the
same value... or at least the same storage location (since they might not
read it at the same time, and without locking the value could change).
Assume I'm talking about a hash because it's been blessed into a class as an
instance (and because I'm curious about the same questions regarding Python,
and its instances are basically hashes).
So then, given that I have two threads which are free-running, I pose these
questions:
* Is "$self->{foo} = $x;" atomic: that is, can I assume that if two threads
start to update $self->{foo} at the "same" time (or one starts updating while
the other starts reading), the one which actually goes first will finish
first?
* Is "$self->{foo}++;" atomic? Ok, I had to ask. ;-) If it was, then the next
generalization would be to ask if a statement which did not invoke a
function, method or system call could be considered atomic: "$self->{foo} +=
$x;", etc.
* Is "$x = $self->{foo};" safe: in otherwords can I assume that if a thread
starts reading $self->{foo}, then even if it's not atomic then assuming this
breaks down into pseudocode something like "dereference $self; compute foo;
use computed foo to dereference $self->{foo}; toss that into $x" can I
presume that $x will at least get either the old or new value of
$self->{foo}... and not some unspecified martian value because the
intermediate got garbage-collected in mid-flight like some instantiation of
Steven King's langoliers?
So does anybody know the answers to these things, as a "true fact" (having
examined the internals, or seen a spec sheet or design doc or discussion
somewhere), for Perl? How about Python?
I suppose the question posed inside-out would be what are the imposed
preconditions for switching thread context in either of these languages?
Why?
Well suppose you have a bunch of threads, and one of them kind of follows the
others around. Let us assume that one is always good about throwing locks
before modifying values. If you're going to that much trouble you could also
raise a flag saying "hey I've got something for ya" but it would be nice if
you could at least look at that flag, with confidence, without having to
throw a lock. So if you're doing that, the inquisitive (me) might as well ask
"when do I have to throw a lock, really?".
(If the answer was "there are no preconditions, 'trust no one'" that would be
sad for DWIMMY languages, and might just prompt me to put yet another "one of
these days" projects onto my long list of things to do with my free time...
it would also become something on my checklist when considering
technologies.)
--
Fred Morris
More information about the spug-list
mailing list