你确实需要一个。尽管多线程在 Python 中的工作方式不同,但由于Global Interpreter Lock,Python 字节码中非原子的操作仍然需要锁定。
在你的情况下,你可以检查你的函数test
(dis.dis(test)
)的字节码:
3 0 SETUP_LOOP 30 (to 33)
3 LOAD_GLOBAL 0 (range)
6 LOAD_CONST 1 (1000)
9 CALL_FUNCTION 1
12 GET_ITER
>> 13 FOR_ITER 16 (to 32)
16 STORE_FAST 0 (i)
4 19 LOAD_GLOBAL 1 (count) # start of increment
22 LOAD_CONST 2 (1)
25 BINARY_ADD
26 STORE_GLOBAL 1 (count) # end of increment
29 JUMP_ABSOLUTE 13
>> 32 POP_BLOCK
>> 33 LOAD_CONST 0 (None)
36 RETURN_VALUE
如您所见,增量是字节码级别的 2xload、update、store,所以这不起作用。增量实际上是 4 个单独的操作,您必须保护它们以确保它们不会被中断。
在您的示例中,即使您使用 ,问题仍然存在count += 1
,如字节码所示:
4 19 LOAD_GLOBAL 1 (count)
22 LOAD_CONST 2 (1)
25 INPLACE_ADD
26 STORE_GLOBAL 1 (count)