Является ли этот код потокобезопасным в Python 2.7?
Должен ли я использовать атомный счетчик с блокировкой или это можно использовать?
def somefunc(someparam):
if someparam:
dic['key'] +=1
2 ответа
Решение
Нет, ваш код не является потокобезопасным, потому что использование +=
расширенное присваивание значения в словаре требует 3 кода операции для выполнения:
>>> dis.dis(compile("dic['key'] += 1", '', 'exec'))
1 0 LOAD_NAME 0 (dic)
3 LOAD_CONST 0 ('key')
6 DUP_TOPX 2
9 BINARY_SUBSCR
10 LOAD_CONST 1 (1)
13 INPLACE_ADD
14 ROT_THREE
15 STORE_SUBSCR
16 LOAD_CONST 2 (None)
19 RETURN_VALUE
Код операции в позиции 9, BINARY_SUBSCR
извлекает текущее значение из словаря Где-нибудь между кодами операций 9 и 15 (где STORE_SUBSCR
возвращает значение обратно), может произойти переключение потока, и другой поток может обновить словарь.
Встроенные структуры Python являются потокобезопасными для отдельных операций. GIL (глобальная блокировка интерпретатора) заботится об этом. Но в основном трудно понять, где оператор становится больше операций.
Добавление блокировки даст вам душевное спокойствие:
def somefunc(someparam):
if someparam:
with lock:
dic['key'] +=1