Python中的GIL

什么是GIL

Python官方解释器(即,CPython解释器)在内部并不是线程安全的,因此它有一个全局解释器锁(GIL),它使得在任何时刻都只有一个线程在执行Python字节码。

这也是使得标准版本的Python并不能实现真正的多线程并发的直接原因。简单来说就是,一个Python进程永远不能在同一时刻使用多个CPU核心。

喜欢Python读者君可以加我们Python学习交流 330637182群每天有资料和视频更新。

解决方案

C扩展

当我们直接书写Python代码的时候,我们并没有能力控制这个GIL锁。但是大多数的内置函数,和用C写的扩展可以释放这个GIL锁。

事实上,用C写的Python库能够管理GIL锁,开启属于它自己的操作系统线程,并且充分利用所有可用的CPU核心。

但是这种方案会极大的提高(提高到恐怖的情况),因此大多数的库开发者,都不会这么做,除非对性能要求非常高的业务逻辑。

Python的自我救赎

但是,所有执行阻塞IO的标准库函数,会在等待操作系统返回结果时释放GIL锁。这意味着使用Python写的I/O密集型任务不会受到Python级别线程的太多限制。

换句话说,当我们有一个Python线程正在等待网络响应的时候,这个阻塞的函数可以释放GIL锁,以便其他线程可以继续执行。

因此,Python程序在执行I/O密集型的任务的时候,是完美可行的,即使是time.sleep()也是一样。

利用多CPU核心

那么,如果不是I/O阻塞的情况,该怎么办呢?此时Python并不能自动释放GIL锁,Python程序员就真的束手无策了嘛?

当然不是,如果对于计算密集型任务,我们推荐使用多进程的方案,分配当前CPU核心数的进程池来处理计算任务。每个进程可以独享一个CPU核心(当然,前提是需要做一点额外的工作),关于这个的详细描述就又是一个很长的理论了,想要深入了解,可以[加入QQ群](330637182),获得经验更加丰富的开发者的帮助。

但是,请注意,对于I/O密集型的任务,使用多线程是对机器性能的极大浪费。这也是很多新手最容易犯的错误。

如何选择

简单来说,就是两条原则

  • 对于计算密集型任务,应该开启多个线程(当然不要太多)来规避GIL锁

  • 特别对于网络请求的问题,可以完全相信Python的多线程,它绝对不会让你失望

很多人都说Python很慢,其实Python的性能已经得到了极大的提升,区别只是你能不能写出如此高性能的代码.

模块选择

如果想要了解本文所说的相关技术,可以试着阅读以下模块

  • Thread、queue

  • multiprocessing

你可能感兴趣的:(Python中的GIL)