Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
540 views
in Technique[技术] by (71.8m points)

python dictionary is thread safe?

Some stated that python dictionary is thread safe. Does it mean I can or cannot modify the items in a dictionary while iterating over it?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The other answers already correctly addressed what's apparently your actual question:

Does it mean I can or cannot modified the items in a dictionary while iterating over it?

by explaining that thread safety has nothing to do with the issue, and in any case, no, you cannot modify a dict while iterating over it.

However, the title of your question is about thread safety, and you start with:

Some stated that python dictionary is thread safe

I don't know who the "some" are, but, if they did state that (rather than you misunderstanding what they did state;-) without heavy qualifications, they're wrong.

Some operations, those which don't alter the set of keys in the dict, happen to be thread-safe in current CPython implementations -- but you should not count on that, unless you strictly control the Python version under which your code will run, because such thread safety is not guaranteed by Python's language specification and therefore other implementations, including future versions of CPython, might not offer it.

If every thread is only "reading" the dict (indexing it, looping on it, etc), and no thread performs any assignment or deletion on it, then that situation is safe in current CPython implementations; in fact, if some thread assigns a new value to a key that was already present, that is also thread safe (other threads may see the previous value for that key, or the next one, depending on how the threads happen to be timed, but there will be no crash, no deadlock, and no appearance of crazy values out of nowhere, in current CPython implementations).

However, an operation such as d[k] += 1 (assuming k was previously present, and its value a number) is not properly speaking thread safe (any more than other case of +=!) because it can be seen as d[k] = d[k] + 1 -- it might happen that two threads in a race condition both read the old value of d[k], then increment it by one, and store the same new value in the slot... so the overall effect is to increment it only by one, and not by two as would normally occur.

Back to your other question... "only reading" the dict, and assigning new values to keys that already existed in the dict, are also the things you can do in the body of a loop that iterates on the dict -- you can't alter the set of keys in the dict (you can't add any key, nor remove any key), but the specific operation of setting a new value for an existing key is allowed. The allowed operations in this case do include the += that would be problematic in a threading situation. For example:

>>> d = dict.fromkeys(range(5), 0)
>>> for k in d: d[k] += 1
... 
>>> d
{0: 1, 1: 1, 2: 1, 3: 1, 4: 1}

and this behavior is guaranteed by Python's standardized semantics, so different implementations of the language should all preserve it.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...