python底层GIL

本文介绍了Python的全局解释器锁(GIL),它是CPython解释器用于管理全局资源的互斥锁。GIL的存在使得在同一时刻,只有一个线程能执行Python字节码。在IO操作或特定条件满足时,GIL会被释放。尽管GIL限制了多线程在多核CPU上的并行执行,但多线程在处理IO密集型任务时仍能提升性能。Python可以通过多进程、换解释器(如Jython)、C扩展或结合进程与协程来解决GIL带来的问题。面试题涉及到GIL的概念、影响以及多线程在爬虫中的应用和性能比较。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

GIL全局解释器锁

在这里插入图片描述

  1. 这是解释器内部的一把锁,确切一点说是CPython解释器内部的一把锁,所以要注意区分 这和我们在Python代码中使用Lock不是一个层面的概念。

GIL产生的背景 在CPython解释内部运行多个线程的时候,每个线程都需要解释器内部申请相应的全局资源,由于C语言本身比较底层造成CPython在管理所有全局资源的时候并不能应对所有线程同时的资源请求,因此为了防止资源竞争而发生错误,对所有线程申请全局资源增加了限制-全局解释器锁。

  1. 言外之意,就是全局解释器就是为了锁定整个解释器内部的全局资源,每个线程想要运行首先获取GIL,而GIL本身又是一把互斥锁,造成所有线程只能一个一个one-by-one-并发-交替的执行。

GIL什么时候释放

  • 在当前线程执行超时后会自动释放
  • 在当前线程执行阻塞操作时会自动释放
  • 当前执行完成时
    Guido的声明:http://www.artima.com/forums/flat.jsp?forum=106&thread=214235 Python之父在观点的最后部分说明 the language doesn’t require the GIL – it’s only the CPython virtual machine that has historically been unable to shed it.

GIL面试题

描述Python GIL的概念, 以及它对python多线程的影响?编写一个多线程抓取网页的程序,并阐明多线程抓取程序是否可比单线程性能有提升,并解释原因。

  1. Python语言和GIL没有半毛钱关系。仅仅是由于历史原因在Cpython虚拟机(解释器),难以移除GIL。
  2. GIL:全局解释器锁。每个线程在执行的过程都需要先获取GIL,保证同一时刻只有一个线程可以执行代码。
  3. 线程释放GIL锁的情况:
  • 在IO操作等可能会引起阻塞的system call之前,可以暂时释放GIL,但在执行完毕后,必须重新获取GIL
  • Python 3.x使用计时器(执行时间达到阈值后,当前线程释放GIL)或Python 2.x,tickets计数达到100.
  1. Python使用多进程是可以利用多核的CPU资源的。
  2. 多线程爬取比单线程性能有提升,因为遇到IO阻塞会自动释放GIL锁

严重问题: 既然CPython解释存在GIL是否意味每个线程在全局变量就不用加Lock互斥锁了呢? 这是一个严重错误的想法,为什么用户操作全局数据还需要加Lock,因为GIL的释放时机我们无法控制-操作非常可能并没有完成,而不像Lock那样我们用完才释放(操作完整)。

GIL小总结

1、gil是什么: 全局解释器器锁
2. gil作用:单核的情况下实现多任务
3. gil解决方案:

1. 进程
2. 换解释器器(javapython)
3. 线程这块代码使⽤用c,java去实现
4. 进程加协程提⾼高效率

Python中的全局解释器锁(GIL)是为了保护Python字节码的解释器核心同时执行,防止多个线程并发修改数据结构而引入的。这意味着,在任何时候,只有一个线程能够执行Python字节码,即使是在多核处理器上也是如此。因此,尽管Python支持多线程,但它并不适用于那些依赖大量CPU计算的任务(即CPU密集型),因为在这种情况下,线程切换频繁,CPU的实际利用率并没有提高。 如果你想要在Python中实现多线程,并且期望充分利用多核CPU,你需要关注以下几个方面: 1. **I/O密集型任务**:Python的`threading`库可以处理I/O密集型任务,因为在等待I/O响应时,GIL会被释放,其他线程可以执行。 2. **多进程**:Python的`multiprocessing`模块提供了一个无GIL的环境,因为它会启动新的进程,而不是共享相同的解释器实例,所以理论上可以实现真正的并行计算。 3. **使用多线程池**:如`concurrent.futures.ThreadPoolExecutor`,它可以帮助管理线程池,将任务分发给各个线程,让它们在等待I/O操作时保持忙碌。 4. **利用第三方库**:有些第三方库,如Celery或multiprocessing.dummy,虽然底层还是基于线程,但由于其工作原理,可能能在某些场景下减轻GIL的影响。 需要注意的是,虽然以上措施可以在某种程度上提升性能,但要完全绕开GIL所带来的限制,可能需要采用更底层的技术,例如Cython扩展或使用Numba进行加速。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值