浅谈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计算程序开始到程序结束的运行时间和程序运行的CPU时间
Nov 28 Python
Python语言的12个基础知识点小结
Jul 10 Python
Python在图片中添加文字的两种方法
Apr 29 Python
Python文件常见操作实例分析【读写、遍历】
Dec 10 Python
TensorFlow卷积神经网络之使用训练好的模型识别猫狗图片
Mar 14 Python
Python动态赋值的陷阱知识点总结
Mar 17 Python
python批量下载抖音视频
Jun 17 Python
Python学习笔记之While循环用法分析
Aug 14 Python
通过Python实现Payload分离免杀过程详解
Jul 13 Python
python爬虫数据保存到mongoDB的实例方法
Jul 28 Python
Pycharm plot独立窗口显示的操作
Dec 11 Python
使用python将HTML转换为PDF pdfkit包(wkhtmltopdf) 的使用方法
Apr 21 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入门的学习方法
2007/01/02 PHP
PHP5中的this,self和parent关键字详解教程
2007/03/19 PHP
php session 检测和注销
2009/03/16 PHP
UTF-8正则表达式如何匹配汉字
2015/08/03 PHP
一个简单至极的PHP缓存类代码
2015/10/23 PHP
Yii2.0 模态弹出框+ajax提交表单
2016/05/22 PHP
PHP使用redis位图bitMap 实现签到功能
2019/10/08 PHP
laravel5环境隐藏index.php后缀(apache)的方法
2019/10/12 PHP
PHP设计模式之组合模式定义与应用示例
2020/02/01 PHP
PHP开发api接口安全验证操作实例详解
2020/03/26 PHP
深入理解PHP+Mysql分布式事务与解决方案
2020/12/03 PHP
用js重建星际争霸
2006/12/22 Javascript
基于jQuery实现下拉收缩(展开与折叠)特效
2012/12/25 Javascript
js内存泄露的几种情况详细探讨
2013/05/31 Javascript
Bootstrap表单布局
2016/07/19 Javascript
JS前端加密算法示例
2016/12/22 Javascript
详解Nodejs的timers模块
2016/12/22 NodeJs
详解JavaScript RegExp对象
2017/02/04 Javascript
JavaScript实现多叉树的递归遍历和非递归遍历算法操作示例
2018/02/08 Javascript
微信小程序实现发送模板消息功能示例【通过openid推送消息给用户】
2019/05/05 Javascript
JS字符串与二进制的相互转化实例代码详解
2019/06/28 Javascript
微信小程序 flexbox layout快速实现基本布局的解决方案
2020/03/24 Javascript
js实现表单项的全选、反选及删除操作示例
2020/06/05 Javascript
[58:46]OG vs NAVI 2019国际邀请赛小组赛 BO2 第二场 8.15
2019/08/17 DOTA
Django中模型Model添加JSON类型字段的方法
2015/06/17 Python
详解python中的 is 操作符
2017/12/26 Python
简单的python协同过滤程序实例代码
2018/01/31 Python
使用Python的Turtle库绘制森林的实例
2019/12/18 Python
Keras自定义IOU方式
2020/06/10 Python
解决pytorch 交叉熵损失输出为负数的问题
2020/07/07 Python
CSS3 linear-gradient线性渐变生成加号和减号的方法
2017/11/21 HTML / CSS
纯CSS3实现鼠标滑过按钮动画第二节
2020/07/16 HTML / CSS
电子商务专业自我鉴定
2013/12/18 职场文书
2014年群众路线党员自我评议
2014/09/24 职场文书
《社戏》教学反思
2016/02/22 职场文书
解决numpy和torch数据类型转化的问题
2021/05/23 Python