作家
登录

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

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

6岁时,我有一个音乐盒。我上紧发条,音乐盒顶上的芭蕾舞女演员就会扭转起来,同时,内部装配发出“一闪一闪亮晶晶,满天都是细姨星”的叮铃声。那玩意儿肯定俗气透了,但我爱好那个音乐盒,我想知道它的工作道理是什么。后来我拆开了,才看到它琅绫擎一个简单的装配,机身内手下嵌着一个拇指大年夜小的金属圆筒,当它迁移转变时会拨弄钢制的梳齿,大年夜而发出这些音符。

(我在本文中只描述 CPython,而不是 Jython、PyPy 或 IronPython。因为今朝绝大年夜多半法度榜样员照样应用 CPython 实现 Python 。)

瞧,全局说冥器锁(GIL)

这里:

  1. static PyThread_type_lock interpreter_lock = 0; /* This is the GIL */ 

这一行代码摘自 ceval.c —— CPython 2.7 说冥器的源代码,Guido van Rossum 的注释”This is the GIL“ 添加于2003 年,但这个锁本身可以追溯到1997年他的第一个多线程 Python 说冥器。在 Unix体系中,PyThread_type_lock 是标准 C mutex_t 锁的别号。当 Python 说冥器启动时它初始化:

即使这一行 lst.sort() 分几个步调,调用 sort 自身是单个字节码,是以线程没有机会在调用时代抓取 GIL 。我们可以总结为在 sort() 不须要加锁。或者,为了避免担心哪个操作是原子的,遵守一个简单的原则:始终环绕共享可变状况的攫取和写入加锁。毕竟,在 Python 中获取一个 threading.Lock 是便宜的。

  1. void 
  2.  
  3. PyEval_InitThreads(void) 
  4.  
  5.  
  6.     interpreter_lock = PyThread_allocate_lock(); 
  7.  
  8.     PyThread_acquire_lock(interpreter_lock); 
  9.  
  10.  
  1. PyThread_release_lock(interpreter_lock); 

说冥器中的所有 C 代码在履行 Python 时必须保持这个锁。Guido 最初加这个锁是因为它应用起来简单。并且每次大年夜 CPython 中去除 GIL 的测验测验会消费单线程法度榜样太多机能,尽管去除 GIL 会带来多线程法度榜样机能的晋升,但仍是不值得的。(前者是Guido最为关怀的, 也是不去除 GIL 最重要的原因, 一个简单的测验测验是在1999年, 最终的结不雅是导致单线程的法度榜样速度降低了几乎2倍.)

GIL 对法度榜样中线程的影响足够简单,你可以在手背楸挤怕这个原则:“一个线程运行 Python ,而其他 N 个睡眠或者等待 I/O.”(即包管同一时刻只有一个线程对共享资本进行存取) Python 线程也可以等待threading.Lock或者线程模块中的其他同步对象;线程处于这种状况也称之为”睡眠“。

线程何时切换?一个线程无论何时开端睡眠或等待收集 I/O,其他线程总有机会获取 GIL 履行 Python 代码。这是协同式多义务处理。CPython 也还有抢占式多义务处理。如不雅一个线程不间断地在 Python 2 中运行 1000 字节码指令,或者不间断地在 Python 3 运行15 毫秒,那么它便会放弃 GIL,而其他线程可以运行。把这想象成旧日有多个线程但只有一个 CPU 时的时光片。我将具体评论辩论这两种多义务处理。

把 Python 看作是旧时的大年夜型主机,多个义务共用一个CPU。

Python中的线程安然

协同式多义务处理

当一项义务比如收集 I/O启动,而在长的或不肯定的时光,没有运行任何 Python 代码的须要,一个线程便会让出GIL,大年夜而其他线程可以获取 GIL 而运行 Python。这种礼貌行动称为协同式多义务处理,它许可并发;多个线程同时等待不合事宜。

也就是说两个线程各自分别连接一个套接字:

  1. def do_connect(): 
  2.  
  3.     s = socket.socket() 
  4.  
  5.     s.connect(('python.org', 80))  # drop the GIL 
  6.  
  7.   
  8.  
  9. for i in range(2): 
     1/6    1 2 3 4 5 6 下一页 尾页

      推荐阅读

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

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


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

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

关键词: 探索发现

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

网友点评
自媒体专栏

评论

热度

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