浅谈Python中的全局锁(GIL)问题


Posted in Python onJanuary 11, 2019

CPU-bound(计算密集型) 和I/O bound(I/O密集型)

计算密集型任务(CPU-bound) 的特点是要进行大量的计算,占据着主要的任务,消耗CPU资源,一直处于满负荷状态。比如复杂的加减乘除、计算圆周率、对视频进行高清解码等等,全靠CPU的运算能力。这种计算密集型任务虽然也可以用多任务完成,但是任务越多,花在任务切换的时间就越多,CPU执行任务的效率就越低,所以,要最高效地利用CPU,计算密集型任务同时进行的数量应当等于CPU的核心数。

计算密集型任务由于主要消耗CPU资源,因此,代码运行效率至关重要。Python这样的脚本语言运行效率很低,完全不适合计算密集型任务。对于计算密集型任务,最好用C语言编写。

IO密集型任务(I/O bound)的特点是指磁盘IO、网络IO占主要的任务,CPU消耗很少,任务的大部分时间都在等待IO操作完成(因为IO的速度远远低于CPU和内存的速度)。

IO密集型任务执行期间,99%的时间都花在IO上,花在CPU上的时间很少,因此,用运行速度极快的C语言替换用Python这样运行速度极低的脚本语言,完全无法提升运行效率。

对于IO密集型任务,任务越多,CPU效率越高,但也有一个限度。常见的大部分任务都是IO密集型任务,比如请求网页、读写文件等。当然我们在Python中可以利用sleep达到IO密集型任务的目的。

对于IO密集型任务,最合适的语言就是开发效率最高(代码量最少)的语言,脚本语言是首选,C语言最差。

全局锁问题:

解释器被一个全局解释器锁保护着,它确保任何时候都只有一个Python线程执行。

GIL最大的问题就是Python的多线程程序并不能利用多核CPU的优势 (比如一个使用了多个线程的计算密集型程序只会在一个单CPU上面运行)。

GIL只会影响到那些严重依赖CPU的程序(比如计算型的)

如果你的程序大部分只会设计到I/O,比如网络交互,那么使用多线程就很合适, 因为它们大部分时间都在等待。实际上,你完全可以放心的创建几千个Python线程, 现代操作系统运行这么多线程没有任何压力,没啥可担心的。

解决方案:

首先,如果你完全工作于Python环境中,你可以使用 multiprocessing 模块来创建一个进程池, 并像协同处理器一样的使用它。

pool = None

# Performs a large calculation (CPU bound)
def some_work(args):
 ...
 return result

def some_thread():
 while True:
  ...
  r = pool.apply(some_work, (args))
  ...

# Initiaze the pool
if __name__ == '__main__':
 import multiprocessing
 pool = multiprocessing.Pool()

另外一个解决GIL的策略是使用C扩展编程技术。 主要思想是将计算密集型任务转移给C,跟Python独立,在工作的时候在C代码中释放GIL。

以上这篇浅谈Python中的全局锁(GIL)问题就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python中为feedparser设置超时时间避免堵塞
Sep 28 Python
Python实现控制台进度条功能
Jan 04 Python
python中子类继承父类的__init__方法实例
Dec 15 Python
Python实现的弹球小游戏示例
Aug 01 Python
python web基础之加载静态文件实例
Mar 20 Python
flask入门之表单的实现
Jul 18 Python
Python3实现的旋转矩阵图像算法示例
Apr 03 Python
ITK 实现多张图像转成单个nii.gz或mha文件案例
Jul 01 Python
Python+pyftpdlib实现局域网文件互传
Aug 24 Python
Python语言编写智力问答小游戏功能
Oct 13 Python
python中sys模块的介绍与实例
Apr 17 Python
python使用pywinauto驱动微信客户端实现公众号爬虫
May 19 Python
Python 实现子类获取父类的类成员方法
Jan 11 #Python
python使用xlrd模块读取xlsx文件中的ip方法
Jan 11 #Python
python远程调用rpc模块xmlrpclib的方法
Jan 11 #Python
解决PySide+Python子线程更新UI线程的问题
Jan 11 #Python
python PrettyTable模块的安装与简单应用
Jan 11 #Python
对python多线程中互斥锁Threading.Lock的简单应用详解
Jan 11 #Python
pyqt5实现俄罗斯方块游戏
Jan 11 #Python
You might like
PHP DataGrid 实现代码
2009/08/12 PHP
Codeigniter实现处理用户登录验证后的URL跳转
2014/06/12 PHP
PHP基于PDO实现的SQLite操作类【包含增删改查及事务等操作】
2017/06/21 PHP
使用正则替换变量
2007/05/05 Javascript
javascript prototype 原型链
2009/03/12 Javascript
Egret引擎开发指南之编译项目
2014/09/03 Javascript
js实现单击图片放大图片的方法
2015/02/17 Javascript
JS实现控制表格行文本对齐的方法
2015/03/30 Javascript
JavaScript中setMonth()方法的使用详解
2015/06/11 Javascript
js实现数组冒泡排序、快速排序原理
2016/03/08 Javascript
JavaScript 巧学巧用
2017/05/23 Javascript
如何重置vue打印变量的显示方式
2017/12/06 Javascript
微信小程序全选多选效果实现代码解析
2020/01/21 Javascript
在vue中实现禁止屏幕滚动,禁止屏幕滑动
2020/07/22 Javascript
利用vue3+ts实现管理后台(增删改查)
2020/10/30 Javascript
vue组件中传值EventBus的使用及注意事项说明
2020/11/16 Javascript
Python中的Descriptor描述符学习教程
2016/06/02 Python
python按照多个条件排序的方法
2019/02/08 Python
pandas中的series数据类型详解
2019/07/06 Python
python networkx 根据图的权重画图实现
2019/07/10 Python
解决Django migrate不能发现app.models的表问题
2019/08/31 Python
Python 求数组局部最大值的实例
2019/11/26 Python
Python中使用gflags实例及原理解析
2019/12/13 Python
Python将列表中的元素转化为数字并排序的示例
2019/12/25 Python
探秘TensorFlow 和 NumPy 的 Broadcasting 机制
2020/03/13 Python
大学本科毕业生的自我鉴定
2013/11/26 职场文书
教师实习自我鉴定
2013/12/18 职场文书
党课学习思想汇报
2014/01/02 职场文书
开学季活动策划方案
2014/02/28 职场文书
会计自荐信范文
2014/03/09 职场文书
建议书标准格式
2014/03/12 职场文书
房屋转让协议书
2014/10/18 职场文书
银行客户经理岗位职责
2015/04/09 职场文书
房产遗嘱范本
2015/08/06 职场文书
golang中的并发和并行
2021/05/08 Golang
Redis模仿手机验证码发送的实现示例
2021/11/02 Redis