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