Применимо ли это к словарям?Или словарь - это набор переменных?
Давайте будем более общими:
Что означает «атомарная операция»?
От Wikipedia :
В параллельном программировании операция (или набор операций) является атомарной, линеаризуемой, неделимой или непрерывной, если кажется, что остальная часть системы происходит мгновенно.Атомность - это гарантия изоляции от параллельных процессов.
Что это значит в Python?
Это означает, что каждая инструкция байт-кода является атомарной (по крайней мере,для Python <3.2, до нового GIL). </p>
Почему это ???
Поскольку Python (CPython) использует Global Interpreter Lock (GIL)) .Интерпретатор CPython использует блокировку, чтобы убедиться, что в интерпретаторе одновременно работает только один поток, и использует «интервал проверки» (см. sys.getcheckinterval()
), чтобы узнать, сколько инструкций байт-кода нужно выполнить перед переключениеммежду потоками (по умолчанию установлено 100).
Итак, что же это значит ??
Это означает, что операции, которые могут быть представлены только одной инструкцией байт-кода,атомное.Например, приращение переменной составляет , а не атомарный, потому что операция выполняется в трех инструкциях байт-кода:
>>> import dis
>>> def f(a):
a += 1
>>> dis.dis(f)
2 0 LOAD_FAST 0 (a)
3 LOAD_CONST 1 (1) <<<<<<<<<<<< Operation 1 Load
6 INPLACE_ADD <<<<<<<<<<<< Operation 2 iadd
7 STORE_FAST 0 (a) <<<<<<<<<<<< Operation 3 store
10 LOAD_CONST 0 (None)
13 RETURN_VALUE
Так что насчет словарей ??
Некоторые операции являются атомарными;например, эта операция является атомарной:
d[x] = y
d.update(d2)
d.keys()
Убедитесь сами:
>>> def f(d):
x = 1
y = 1
d[x] = y
>>> dis.dis(f)
2 0 LOAD_CONST 1 (1)
3 STORE_FAST 1 (x)
3 6 LOAD_CONST 1 (1)
9 STORE_FAST 2 (y)
4 12 LOAD_FAST 2 (y)
15 LOAD_FAST 0 (d)
18 LOAD_FAST 1 (x)
21 STORE_SUBSCR <<<<<<<<<<< One operation
22 LOAD_CONST 0 (None)
25 RETURN_VALUE
Смотрите этот , чтобы понять, что делает STORE_SUBSCR.
Но, как вы видите, это не совсем так, потому что эта операция:
...
4 12 LOAD_FAST 2 (y)
15 LOAD_FAST 0 (d)
18 LOAD_FAST 1 (x)
...
может сделать всю операцию не атомарной.Зачем?Допустим, переменная x также может быть изменена другим потоком ... или что вы хотите, чтобы другой поток очистил ваш словарь ... мы можем назвать много случаев, когда она может пойти не так, поэтому это сложно!И поэтому здесь мы будем применять Закон Мерфи : «Все, что может пойти не так, пойдет не так».
И что теперь?
ЕслиВы все еще хотите разделить переменные между потоками, используйте блокировку:
import threading
mylock = threading.RLock()
def atomic_operation():
with mylock:
print "operation are now atomic"