【问题标题】:CPython and threading module Lock()CPython 和线程模块 Lock()
【发布时间】:2016-07-19 20:51:49
【问题描述】:

由于 CPython 有 GIL,不允许线程同时执行 python 代码,因此在给定进程中似乎存在线程安全。

那么python线程模块Lock ()的目的是什么?即使没有线程可以同时执行,Lock () 帮助解决的 CPython 中仍然会出现哪些同步问题?

【问题讨论】:

    标签: python-3.x python-multithreading cpython


    【解决方案1】:

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

    【讨论】:

    • 非常好的答案!谢谢
    猜你喜欢
    • 2012-07-11
    • 1970-01-01
    • 2011-06-26
    • 1970-01-01
    • 2014-06-25
    • 1970-01-01
    • 2021-10-11
    • 2017-03-14
    • 2014-08-21
    相关资源
    最近更新 更多