python GIL

    讲GIL之前先弄清楚几个小概念

1. 同步IO&异步IO

   同步IO:当程序执行到IO操作时,等数据来了才进行下一步操作,数据不来就阻塞在IO操作处。

   异步IO:当程序执行到IO操作时,不等,就去执行其他代码了。一段时间后,当IO返回结果时,再通知CPU进行处理。

如何实现异步IO也是一个问题,到时候另讲。

2. 并行&并发

   并行:系统具有同时处理多任务的能力,由多CPU同时运行实现。

   并发:系统具有处理多任务的能力,单核CPU就能实现,由CPU分时轮循任务实现。

3. 多任务分类

  IO密集型与计算密集型


GIL(全局解释锁)----CPython解释器才有:

       对一个进程,无论你启动多少个线程,你有多少个cpu,python在执行的时候会淡定的在同一时刻只允许一个线程运行。

问题1:CPython解释器为何要对进程加GIL锁?

因为GIL能很好的保护线程安全,而龟叔认为保证线程安全比实现并行更重要。

问题2:那python对于处理多任务的情况怎么办?

对于IO密集型多任务,CPython会在IO阻塞时将线程转为阻塞状态,换其他就绪状态线程执行。这样对于IO密集型多任务用多线程就可以大大提高CPU利用率(任然时单核)。

对于计算密集型多任务,有多种替代方案可选①:多进程+协程;②:用python提供的扩展接口将计算密集型多任务程序由C语言实现,即让C来实现真正的并发操作,而将计算结果返回给python接口。光靠Python是无法从根本上实现计算密集型多任务的并行。

问题3:什么时候释放GIL锁?

①:1 遇到像 i/o操作这种 会有时间空闲情况 造成cpu闲置的情况会释放Gil

②:会有一个专门ticks进行计数 一旦ticks数值达到100 这个时候释放Gil锁 线程之间开始竞争Gil锁(说明:ticks这个数值可以进行设置来延长或者缩减获得Gil锁的线程使用cpu的时间)

问题4: 互斥锁和GIL锁的关系

GIL锁  : 保证同一时刻只有一个线程能使用到cup

互斥锁 : 多线程时,保证修改共享数据时有序的修改,不会产生数据修改混乱


首先假设只有一个进程,这个进程中有两个线程 Thread1,Thread2, 要修改共享的数据date, 并且有互斥锁
执行以下步骤
(1)多线程运行,假设Thread1获得GIL可以使用cpu,这时Thread1获得 互斥锁lock,Thread1可以改date数据(但并
没有开始修改数据)
(2)Thread1线程在修改date数据前发生了 i/o操作 或者 ticks计数满100 (注意就是没有运行到修改data数据),这个
时候 Thread1 让出了Gil,Gil锁可以被竞争
(3) Thread1 和 Thread2 开始竞争 Gil (注意:如果Thread1是因为 i/o 阻塞 让出的Gil Thread2必定拿到Gil,如果
Thread1是因为ticks计数满100让出Gil 这个时候 Thread1 和 Thread2 公平竞争)
(4)假设 Thread2正好获得了GIL, 运行代码去修改共享数据date,由于Thread1有互斥锁lock,所以Thread2无法更改共享数据
date,这时Thread2让出Gil锁 , GIL锁再次发生竞争 

猜你喜欢

转载自blog.csdn.net/m0_37519490/article/details/80497813