Python 多线程因为GIL的存在,导致其速度比单线程还要慢。但是近期我发现了一个相当好用的库,这个库只需要增加一个修饰符就可以使原生的python多线程实现真正意义上的并发。本文将和大家一起回顾下GIL对于多线程的影响,以及了解通过一个修饰符就可以实现和C++一样的多线程。
GIL的定义
GIL的全称是global interpreter lock,官方的定义如下:
In CPython, the global interpreter lock, or GIL, is a mutex that prevents multiple native threads from executing Python bytecodes at once. This lock is necessary mainly because CPython’s memory management is not thread-safe. (However, since the GIL exists, other features have grown to depend on the guarantees that it enforces.)
从官方的解释来看,这个全局锁是用来防止多线程同时执行底层计算代码的。之所以这么做,是因为底层库Cpython,在内存管理这块是线程不安全的。
GIL有好处吗
对GIL的第一印象是这东西限制了多线程并发,对python而言是个弊大于利的存在。但是从stackoverflow上的讨论来看,这个存在还是相当有必要的。
- 增加了单线程的运行速度
- 可以更方便地整合一些线程不安全的C语言库到python里面去
首先单线程的运行速度更快了,因为有这个全局锁的存在,在执行单线程计算的时候不需要再额外增加锁,减少了不必要的开支。第二个则是可以更好地整合用C语言所写的python库。现在其实挺多用C语言写好底层计算然后封装提供python接口的,比如数据处理领域的pandas库,人工智能领域的计算框架Tensorflow或者pytorch,他们的底层计算都是用C语言写的。由于这个全局锁的存在,我们可以更方便(安全)地把这些C语言的计算库整合成一个python包,对外提供python接口。
GIL对性能的影响大吗
对于需要做大量计算的任务而言,影响是相当大的。我们先来看一段单线程代码:
class A(object):
def run(self):
ans