Thread-safe way to add a key to a dict only if it isn't already there?
steve+comp.lang.python at pearwood.info
Sun Jul 8 09:38:17 EDT 2018
On Sun, 08 Jul 2018 14:11:58 +0300, Marko Rauhamaa wrote:
> Steven D'Aprano <steve+comp.lang.python at pearwood.info>:
>> Changing implementations from one which is thread safe to one which is
>> not can break people's code, and shouldn't be done on a whim.
>> Especially since such breakage could be subtle, hard to notice, harder
>> to track down, and even harder still to fix.
> Java's HotSpot does it all the time, and it did result in code breakage
> -- although the code was broken to begin with.
I said "shouldn't be done", rather than claiming that was the situation
right now with all compilers.
But I'm willing to give a little bit of slack to aggressively optimizing
compilers, provided they come with a warning.
>> So there is no coherent way to get a result of "impossible" from just
>> adding 1 to 1 in any coherent implementation of Python.
> Back to Java, there was a real case of 64-bit integer operations not
> being atomic on 32-bit machines. Mixing up upper and lower halves
> between threads could result in really weird evaluations.
Oh don't get me wrong, I agree with you that threading can result in
strange, unpredictable errors.
That's why I try not to use threading. I have no illusions about my
ability to debug those sorts of problems.
> More importantly, this loop may never finish:
> # Initially
> quit = False
> # Thread 1
> global quit
> while not quit:
> # Thread 2
> global quit
> quit = True
Assuming that thread 2 actually runs *at some point*, I don't see how
that can't terminate. Neither thread sets quit to False, so provided
thread 2 runs at all, it has to terminate.
I suppose if the threading implementation *could* fall back to sequential
code (thread 2 doesn't run until thread 1 finishes, which it never
does...) that outcome is possible. But it would have to be a pretty poor
Now if you said there were fifty threads (aside from the main thread,
which is guaranteed to run) all reading quit, and only thread 50 ever
assigns to it, I'd believe that perhaps thread 50 never gets a chance to
run. But with just two threads? Explain please.
> That's the reality in Java and C. I see no reason why that wouldn't be
> the reality in Python as well -- unless the language specification said
Because the Python core developers care more about correctness than speed.
> PS My example with "impossible" being the result of a racy integer
> operation is of course unlikely but could be the outcome if the Python
> runtime reorganized its object cache on the fly (in a hypothetical
That would be a cache bug :-)
Not every interpreter bug should be considered the caller's fault :-)
"Ever since I learned about confirmation bias, I've been seeing
it everywhere." -- Jon Ronson
More information about the Python-list