这段代码在 python 2.7 中是线程安全的吗?
Is this code thread-safe in python 2.7?
我应该使用带有锁定的原子计数器还是可以使用它?
def somefunc(someparam):
if someparam:
dic['key'] +=1
不,您的代码不是线程安全的,因为对字典值使用 +=
扩充赋值需要执行 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
我应该使用带有锁定的原子计数器还是可以使用它?
def somefunc(someparam):
if someparam:
dic['key'] +=1
不,您的代码不是线程安全的,因为对字典值使用 +=
扩充赋值需要执行 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