当前位置:首页 > 科技  > 软件

一文理解Python的全局解释器锁(GIL)

来源: 责编: 时间:2024-04-02 17:18:03 93观看
导读前言• 在Python中,全局解释器锁(Global Interpreter Lock,简称GIL)是一个重要的概念,它对Python解释器的并发执行模型产生了重大影响。本文将介绍GIL的概念、原理以及对Python多线程程序执行效率的影响,并附带详细的代码案

前言

• 在Python中,全局解释器锁(Global Interpreter Lock,简称GIL)是一个重要的概念,它对Python解释器的并发执行模型产生了重大影响。本文将介绍GIL的概念、原理以及对Python多线程程序执行效率的影响,并附带详细的代码案例进行说明。IUH28资讯网——每日最新资讯28at.com

什么是 GILIUH28资讯网——每日最新资讯28at.com

• GIL是Python解释器中的一个互斥锁,它确保在同一时刻只有一个线程能够执行Python字节码。这意味着在多线程环境下,Python解释器无法同时利用多个CPU核心进行并行执行,因为只有一个线程能够执行Python字节码指令。IUH28资讯网——每日最新资讯28at.com

GIL 的工作原理

• 当Python解释器运行Python代码时,它会获取GIL,然后执行相应的字节码指令。其他线程想要执行Python字节码时,必须先获取GIL,但只有在当前线程释放GIL后才能获得。因此,只有一个线程能够在任意时刻执行Python字节码,这就是GIL的工作原理。IUH28资讯网——每日最新资讯28at.com

GIL 的影响

多线程

• 尽管Python完全支持多线程编程, 但是解释器的C语言实现部分在完全并行执行时并不是线程安全的。 实际上,解释器被一个全局解释器锁保护着,它确保任何时候都只有一个Python线程执行。 GIL最大的问题就是Python的多线程程序并不能利用多核CPU的优势 (比如一个使用了多个线程的计算密集型程序只会在一个单CPU上面运行)。IUH28资讯网——每日最新资讯28at.com

• 有一点要强调的是GIL只会影响到那些严重依赖CPU的程序(比如计算型的)。 如果你的程序大部分只会涉及到I/O,比如网络交互,那么使用多线程就很合适, 因为它们大部分时间都在等待。IUH28资讯网——每日最新资讯28at.com

• 对于依赖CPU的程序,你需要弄清楚执行的计算的特点。 例如,优化底层算法可能要比使用多线程运行快得多。 类似的,由于Python是解释执行的,如果你将那些性能瓶颈代码移到一个C语言扩展模块中, 速度也会提升的很快。如果你要操作数组,那么使用NumPy这样的扩展会非常的高效。 最后,你还可以考虑下其他可选实现方案,比如PyPy,它通过一个JIT编译器来优化执行效率。IUH28资讯网——每日最新资讯28at.com

多进程

• 在 Python 中,GIL(全局解释器锁)只影响到了多线程,而不会对多进程产生直接的影响。多进程是通过创建不同的 Python 解释器来实现的,因此每个进程都有自己的独立 GIL,它们之间互不影响。IUH28资讯网——每日最新资讯28at.com

如何解决 GIL 的缺点

示例代码

• 代码版本 Python 3.xIUH28资讯网——每日最新资讯28at.com

• 如我们如何优化下列代码:IUH28资讯网——每日最新资讯28at.com

# Performs a large calculation (CPU bound)def some_work(args):    ...    return result# A thread that calls the above functiondef some_thread():    while True:        ...        r = some_work(args)    ...

使用多进程的方式

• 如果你完全工作于Python环境中,你可以使用 multiprocessing 模块来创建一个进程池, 并像协同处理器一样的使用它,每个进程有独立的 GIL。IUH28资讯网——每日最新资讯28at.com

# Processing pool (see below for initiazation)pool = None# Performs a large calculation (CPU bound)def some_work(args):    ...    return result# A thread that calls the above functiondef some_thread():    while True:        ...        r = pool.apply(some_work, (args))        ...# Initiaze the poolif __name__ == '__main__':    import multiprocessing    pool = multiprocessing.Pool()

使用C扩展编程技术

• 主要思想是将计算密集型任务转移给C,跟Python独立,在工作的时候在C代码中释放GIL。 可以通过在C代码中插入下面这样的特殊宏来完成:IUH28资讯网——每日最新资讯28at.com

#include "Python.h"...PyObject *pyfunc(PyObject *self, PyObject *args) {   ...   Py_BEGIN_ALLOW_THREADS   // Threaded C code   ...   Py_END_ALLOW_THREADS   ...}

• 如果使用其他工具访问C语言,比如对于Cython的ctypes库,你不需要做任何事。 例如,ctypes在调用C时会自动释放GIL。IUH28资讯网——每日最新资讯28at.com

参考

• 12.9 Python的全局锁问题IUH28资讯网——每日最新资讯28at.com

本文链接:http://www.28at.com/showinfo-26-80834-0.html一文理解Python的全局解释器锁(GIL)

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: 并发协调神器CountDownLatch和CyclicBarrier

下一篇: C++ 八种常见类类型

标签:
  • 热门焦点
Top