zoukankan      html  css  js  c++  java
  • 谈谈有关 Python 的GIL 和 互斥锁

    转载:https://blog.csdn.net/Amberdreams/article/details/81274217

    有 Python 开发经验的人也许听说过这样一句话:Python 不能充分利用 CPU 的多核优势。这句话是正确的。

    为什么 Python 不能够利用CPU 的多核优势呢?简单来说就是因为在 Python 中存在 GIL,即global interpreter lock(全局解释器锁)。Python 程序尽管也支持多线程,但由于受到 GIL 的保护,所以同一时刻,只有一条线程可以向前执行。

    接下来我们详细谈谈 Python 中存在的 GIL。

    标准的 Python 实现叫做 CPython。CPython 分两步来运行 Python 程序。

    ① 把文本形式的源代码解析并编译成字节码。

    ② 用一种基于栈的解释器来运行这份字节码。

    执行 Python 程序时,字节码解释器必须保持协调一致的状态。那么怎么才能够保持协调一致的状态呢?

    Python 采用 GIL 机制来确保这种协调性。

    GIL 实际就是一把互斥锁,用以防止 CPython 受到占先式多线程切换操作的干扰。所谓占先式多线程切换,是指某个线程可以通过打断另外一个线程的方式,来获取程序控制权。

    假如这种干扰操作的执行时机不恰当,那就会破坏解释器的状态。

    正是因为存在 GIL,那么这些干扰操作就不会发生了。GIL 可以保证每条字节码指令能够正确的与 CPython 实现及其 C 语言扩展模块协同运作。

    既然 Python 不能充分利用 CPU 的多核优势,那么为什么还要支持多线程呢?

    这是因为:

    ① 多线程使得程序看上去好像能够在同一时间做许多事情。

    借助多线程,则能够令 Python 程序自动以一种看似平行的方式来执行线程调用的函数。这是因为 CPython 在执行 Python 线程的时候,可以保证一定程度的公平,但不是绝对的公平。由于受到 GIL 的限制,所以同一时刻实际上只能有一个线程得到执行。

    ② 在处理阻塞式的 I/O 操作,Python 在执行某些系统调用时,会触发多线程操作。

    我们知道读写文件、在网络间通信、以及与显示器等设备相交互等,都属于阻塞式的 I/O 操作。为了响应这种阻塞式的请求,操作系统必须花一些时间,开发者可以借助多线程,把 Python 程序与这些耗时的 I/O 操作隔离开。

    尽管受制于 GIL,但是用多个 Python 线程来执行系统调用的时候,这些系统调用可以可以平行的执行。GIL 虽然使得 Python代码无法并行,但它对系统调用却没有任何负面影响。

    明白了 GIL 机制之后,也许你会认为在编写Python 代码时,就不需要再使用互斥锁了。

    实际上 GIL 并不会保护开发者自己编写的代码。这是因为同一时刻固然只能有一个 Python 线程得到执行,但是,当这个线程正在操作某个数据结构的时候,其他线程可能会打断它,一旦发生这种现象,就会破坏程序的状态,从而使相关的数据结构无法保持其一致性。为了保证所有线程能够得到公平地执行,Python 解释器会给每个线程分配大致相等的处理器时间。为了达到这样的分配策略,Python 系统可能当某个线程正在执行的时候将其暂停,然后使另一个线程继续往下执行。由于我们无法提前获知 Python 系统会在何时暂停这些线程,所以我们无法控制程序中某些操作是原子操作。

    为了防止线程中出现数据竞争的行为,使开发者可以保护自己的数据结构不受破坏,Python 在 threading 模块中提供了最简单、最有用的工具:Lock 类,该类相当于互斥锁。

    在开发中我们可以使用互斥锁来保护某个对象,使得在多线程同时访问某个对象的时候,不会将该对象破坏。因为同一时刻,只有一个线程能够获得这把锁。也就是说对将要访问的对象进行隔离,那么使用线程隔离的意义在于:是当前线程能够正确的引用到它自己创造的对象,而不是引用到其它线程锁创建的对象。

    讲到这里你应该明白:在 Python 开发中多线程不在是鸡肋的原因了

  • 相关阅读:
    Parrot虚拟机
    JAVA数据结构二叉排序树
    mysql基本操作
    ruby数组操作
    JAVA核心技术之球体碰撞多线程版
    JAVA数据结构选择排序
    JAVA的线程让步
    Perl 与数学:一份快速参考
    科学计算软件包python(x,y)简介
    JAVA数据结构解析数学表达式
  • 原文地址:https://www.cnblogs.com/shengguorui/p/11940371.html
Copyright © 2011-2022 走看看