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 ,存储的值将会不同。

链接地址: http://www.djcxy.com/p/86489.html

上一篇: CPython and threading module Lock()

下一篇: Why single python process's cpu usage can be more than 100 percent?