CPython和线程模块Lock()
由于CPython具有GIL,因此不允许线程同时执行python代码,因此在给定进程中似乎存在线程安全性。
python线程模块Lock ()
的目的是什么? 即使没有线程可以同时执行, Lock ()
帮助的CPython中仍然会发生什么同步问题?
GIL只确保一次只能运行一个线程。 线程在指令之间被中断,而另一个线程有机会运行。 因此,如果两个线程访问共享资源,则需要使用锁来保护访问。
我们来看一下这个例子:
from threading import Thread
i = 0
def func():
global i
while i < 1000000:
i += 1
if i != i:
print("i was modified")
for _ in range(10):
Thread(target=func).start()
虽然它看起来像if
条件不能永远可能是真实的,还有的是,你会看到打印的线的好机会。 怎么可能?
如果您查看func
的反汇编字节码(通过从dis
模块中调用dis.dis(func)
),您将得到以下结果:
7 0 SETUP_LOOP 51 (to 54)
>> 3 LOAD_GLOBAL 0 (i)
6 LOAD_CONST 1 (1000000)
9 COMPARE_OP 0 (<)
12 POP_JUMP_IF_FALSE 53
8 15 LOAD_GLOBAL 0 (i)
18 LOAD_CONST 2 (1)
21 INPLACE_ADD
22 STORE_GLOBAL 0 (i)
9 25 LOAD_GLOBAL 0 (i)
28 LOAD_GLOBAL 0 (i)
31 COMPARE_OP 3 (!=)
34 POP_JUMP_IF_FALSE 3
10 37 LOAD_GLOBAL 1 (print)
40 LOAD_CONST 3 ('i was modified')
43 CALL_FUNCTION 1 (1 positional, 0 keyword pair)
46 POP_TOP
47 JUMP_ABSOLUTE 3
50 JUMP_ABSOLUTE 3
>> 53 POP_BLOCK
>> 54 LOAD_CONST 0 (None)
57 RETURN_VALUE
相关的指令是25和28.如果线程在这两条指令之间被中断,另一个therad可以修改全局变量i
,存储的值将会不同。
上一篇: CPython and threading module Lock()
下一篇: Why single python process's cpu usage can be more than 100 percent?