作家
登录

深入理解GIL:如何写出高性能及线程安全的Python代码

作者: 来源: 2017-05-26 11:06:13 阅读 我要评论

  •  
  • def foo(): 
  •  
  •     global n 
  •  
  •     n += 1  
  • 我们可以看到这个函数用 Python 的标准 dis 模块编译的字节码:

    1. >>> import dis 
    2.  
    3. >>> dis.dis(foo) 
    4.  
    5. LOAD_GLOBAL              0 (n) 
    6.  
    7. LOAD_CONST               1 (1) 
    8.  
    9. INPLACE_ADD 
    10.  
    11. STORE_GLOBAL             0 (n)  

    代码的一行中, n += 1,被编译成 4 个字节码,进行 4 个根本操作:

    1. 将 n 值加载到客栈上
    2. 将常数 1 加载到客栈上
    3. 将客栈顶部的两个值相加
    4. 将总和存储回 n

    记住,一个线程每运行 1000 字节码,就会被说冥器打断夺走 GIL 。如不雅命运运限不好,这(打断)可能产生在线程加载 n 值到客栈时代,以及把它存储回 n 时代。很轻易可以看到这个过程会若何导致更新损掉:

    在一个法度榜样员具备的所有特点中,想商量事物运转规律的┞封种好奇心必弗成少。当我打开音乐盒,不雅察内部装配,可以看出即使我没有成长为一个卓越的法度榜样员,至少也是有好奇心的一个。

    1. threads = [] 
    2.  
    3. for i in range(100): 
    4.  
    5.     t = threading.Thread(target=foo) 
    6.  
    7.     threads.append(t) 
    8.  
    9. for t in threads: 
    10.  
    11.     t.start() 
    12.  
    13. for t in threads: 
    14.  
    15.     t.join() 
    16.  
    17. print(n)  

    平日这个代码输出 100,因为 100 个线程每个都递增 n 。但有时你会看到 99 或 98 ,如不雅一个线程的更新被另一个覆盖。

    1. n = 0 
    2.  
    3. lock = threading.Lock() 
    4.  
    5. def foo(): 
    6.  
    7.     global n 
    8.  
    9.     with lock: 
    10.  
    11.         n += 1  

    如不雅我们应用一个原子操作比如 sort() 函数会若何呢?:

    1. lst = [4, 1, 3, 2] 
    2.  
    3. def foo(): 
    4.  
    5.     lst.sort()  

    这个函数的字节码显示 sort() 函数不克不及被中断,因为它是原子的:

    1. >>> dis.dis(foo) 
    2.  
    3. LOAD_GLOBAL              0 (lst) 
    4.  
    5. LOAD_ATTR                1 (sort) 
    6.  
    7. CALL_FUNCTION            0 

        推荐阅读

        公有云账单:忽略这四项成本,后果很严重!

      中断产生,并由中断导致的宕机,将导致云用户的收入受损。这些故障也可能对企业的荣誉产生晦气影响,即使问题已经解决了几个礼拜或几个月。比拟于本地基本架构,公有云计算平日会削减企业>>>详细阅读


      本文标题:深入理解GIL:如何写出高性能及线程安全的Python代码

      地址:http://www.17bianji.com/lsqh/35440.html

    关键词: 探索发现

    乐购科技部分新闻及文章转载自互联网,供读者交流和学习,若有涉及作者版权等问题请及时与我们联系,以便更正、删除或按规定办理。感谢所有提供资讯的网站,欢迎各类媒体与乐购科技进行文章共享合作。

    网友点评
    自媒体专栏

    评论

    热度

    精彩导读
    栏目ID=71的表不存在(操作类型=0)