Thread-safe way to add a key to a dict only if it isn't already there?

Marko Rauhamaa marko at pacujo.net
Sun Jul 8 12:11:43 EDT 2018


MRAB <python at mrabarnett.plus.com>:
> On 2018-07-08 14:38, Steven D'Aprano wrote:
>> On Sun, 08 Jul 2018 14:11:58 +0300, Marko Rauhamaa wrote:
>>
> [snip]
>>> More importantly, this loop may never finish:
>>>
>>>     # Initially
>>>     quit = False
>>>
>>>     # Thread 1
>>>     global quit
>>>     while not quit:
>>>         time.sleep(1)
>>>
>>>     # 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.
>>
> [snip]
>
> The compiler could look at the code for thread 1 and see that 'quit' is
> never assigned to, meaning that it could be "optimised" to:
>
>     global quit
>     if not quit:
>         while True:
>             time.sleep(1)
>
> In C you'd declare 'quit' as 'volatile' to tell the compiler that it
> could change unexpectedly, so don't make that assumption.

C is an even tougher case. Even if the compiler kept on checking a
volatile value, the CPU might never propagate the cache content to the
other core. You'd need a memory barrier. In Java, "volatile" effectively
creates a memory barrier, but in C (and C++) it does not. In C you need
something like a mutex to see the effects of other threads running.

(BTW, I think that's a terrible thing for the C standards committee to
specify.)


Marko



More information about the Python-list mailing list