Python GIL

1.什么是 GIL?

GIL 全称 Global Interpreter Lock,全局解释器锁,为 CPython 最为人诟病的地方之一。

GIL 允许我们一次只有一个线程运行在一个 CPU 上执行字节码。

GIL 为了线程运行安全,加了一把非常大的锁,不过这也使得多线程执行效率不高。无法发挥多核心的优势,并发性能非常的受限。

无法将多个线程映射到多个 CPU 上

但是!

import threading

total = 0

def add():
    global total
    for i in range(1000000):
        total += 1

    
def desc():
    global total
    for i in range(1000000):
        total -= 1

thread1 = threading.Thread(target=add)
thread2 = threading.Thread(target=desc)

thread1.start()
thread2.start()

thread1.join()
thread2.join()

print(total)

输出结果并不会一样。

可以看到,GIL 不会一直占有。会释放的,然后另外的线程便可以执行。

那么什么情况下会释放 GIL ?

会根据执行的字节码行数以及时间片来释放 GIL
或者遇到 IO 操作的时候主动释放 GIL,这属于 Python 内部的策略问题。

协同式多任务处理

当一项任务比如网络 I/O启动,而在长的或不确定的时间,没有运行任何 Python 代码的需要,一个线程便会让出GIL,从而其他线程可以获取 GIL 而运行 Python。这种礼貌行为称为协同式多任务处理,它允许并发;多个线程同时等待不同事件。

抢占式多任务处理

Python线程可以主动释放 GIL,也可以先发制人抓取 GIL 。

让我们回顾下 Python 是如何运行的。你的程序分两个阶段运行。首先,Python文本被编译成一个名为字节码的简单二进制格式。第二,Python解释器的主回路,一个名叫 pyeval_evalframeex() 的函数,流畅地读取字节码,逐个执行其中的指令。

当解释器通过字节码时,它会定期放弃GIL,而不需要经过正在执行代码的线程允许,这样其他线程便能运行:

for (;;) {
    if (--ticker < 0) {
        ticker = check_interval;
 
        /* Give another thread a chance */
        PyThread_release_lock(interpreter_lock);
 
        /* Other threads may run now */
 
        PyThread_acquire_lock(interpreter_lock, 1);
    }
 
    bytecode = *next_instr++;
    switch (bytecode) {
        /* execute the next instruction ... */ 
    }
}

默认情况下,检测间隔是1000 字节码。所有线程都运行相同的代码,并以相同的方式定期从他们的锁中抽出。在 Python 3 GIL 的实施更加复杂,检测间隔不是一个固定数目的字节码,而是15 毫秒。然而,对于你的代码,这些差异并不显著。

Python GIL其实是功能和性能之间权衡后的产物,它尤其存在的合理性,也有较难改变的客观因素。从本分的分析中,我们可以做以下一些简单的总结:

  • 因为GIL的存在,只有IO Bound场景下得多线程会得到较好的性能
  • 如果对并行计算性能较高的程序可以考虑把核心部分也成C模块,或者索性用其他语言实现
  • GIL在较长一段时间内将会继续存在,但是会不断对其进行改进

其实 GIL 算不得是低效的设计,其坏处在于锁的粒度太粗。

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 前言 本篇文章主要是看完UnderstandingGIL.pdf后的一些理解 http://www.dabeaz....
    钢筋铁骨阅读 5,132评论 0 50
  • GIL 是什么东西?它对我们的 python 程序会产生什么样的影响? 我们先来看一个问题。运行下面这段 pyth...
    lintong阅读 5,339评论 0 32
  • GIL是什么 GIL并不是Python的特性,它是在实现Python解析器(CPython)时所引入的一个概念,而...
    StormZhu阅读 9,524评论 0 3
  • 陈远坤已经四年没有谈女朋友据说是因为许静,陈远坤已经退出小说界了。我很真的很喜欢他写得每一本小说。 关注新浪微博:...
    陈远坤阅读 1,014评论 0 0
  • 感觉这是一部被低估的电影。非常喜欢这部电影的故事讲述方式和构图。故事以中国传统说书的形式展开,画外音和配乐极具京味...
    燕西行阅读 1,631评论 0 0