Thread Safety

Clarence Gardner clarence at netlojix.com
Tue Jan 30 13:10:20 EST 2001


I'll make a last contribution to this thread, reiterating Timmy's wisdom:
>cleverness-is-the-#1-cause-of-thread-bugs-ly y'rs  - tim
and
>"thread safety" is not an absolute judgment

I received a message in email saying that my function was thread-safe
after all:

> >> Python executes bytecodes atomically, but makes no guarantees beyond that.
> >> Do you still think you're "threadsafe"?
> > Nope.
> You'd be wrong.
> > [...] given that the function shown is the only place that
> > the Pending... names are bound (other than initialization).
> That's why you're wrong.
> > answer to "That's not safe, no".  Given the need for mutex, I'll change
> > them to classes, I think.
> [...]
> > Of course, I'll need to protect all the additions to the lists, also.
> You don't need a mutex, and you don't need to protect any additions to
> (or removals from) the lists.  As long as nothing else _assigns_
> ("binds" by the common Pythonic misuse of that word) the global
> variable, which you've said above isn't going to happen, there's no
> possibility of losing items.  It doesn't make the slightest difference
> whether you use
>   data, Pending... = Pending..., []
> or
>   data = Pending...
>   Pending... = []
> though; either way is thread-safe given the above condition.

Now, my original question related to the
    Data,PendingDataStorage = PendingDataStorage,[]
type of statements, but nonetheless, with respect to the actual context,
    Data,PendingDataStorage = PendingDataStorage,[]
    if Data:
        StoreDataPoints(Data)
this is not safe; even though an append to PendingDataStorage done elsewhere
will not be lost (it will appear in either Data or the new PendingDataStorage),
it might appear in Data *after* the StoreDataPoints function runs, which is
effectively the same as losing it.

Looking at code for the append,
         18 LOAD_GLOBAL              1 (PendingDataStorage)
         21 LOAD_ATTR                2 (append)
         24 LOAD_FAST                0 (data)
         27 CALL_FUNCTION            1
this situation would arise if StoreDataPoints is called (and completes) after
instruction #18 and before #27.

cleverness?-I've-got-some-cheap-ly y'rs - clarence

(I said in a post almost three years ago that I wouldn't cheapen Tim's
signature art form with my pedestrian attempts; I guess I lied :) )



More information about the Python-list mailing list