浅谈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爬虫 正则表达式使用技巧及爬取个人博客的实例讲解
Oct 20 Python
人机交互程序 python实现人机对话
Nov 14 Python
Python各类图像库的图片读写方式总结(推荐)
Feb 23 Python
python实现在图片上画特定大小角度矩形框
Oct 24 Python
Python pandas DataFrame操作的实现代码
Jun 21 Python
Django高级编程之自定义Field实现多语言
Jul 02 Python
基于python实现雪花算法过程详解
Nov 16 Python
python 微信好友特征数据分析及可视化
Jan 07 Python
python实现根据给定坐标点生成多边形mask的例子
Feb 18 Python
keras分类模型中的输入数据与标签的维度实例
Jul 03 Python
python 逆向爬虫正确调用 JAR 加密逻辑
Jan 12 Python
PyQt5 QThread倒计时功能的实现代码
Apr 02 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
Can't create/write to file 'C:\WINDOWS\TEMP\...MYSQL报错解决方法
2011/06/30 PHP
PHP实现生成模糊图片的方法示例
2017/12/21 PHP
基于Laravel 多个中间件的执行顺序详解
2019/10/21 PHP
简单的php购物车代码
2020/06/05 PHP
js 内存释放问题
2010/04/25 Javascript
js实现class样式的修改、添加及删除的方法
2015/01/20 Javascript
js实现图片从左往右渐变切换效果的方法
2015/02/06 Javascript
在Javascript中处理字符串之big()方法的使用
2015/06/08 Javascript
js阻止冒泡和默认事件(默认行为)详解
2016/10/20 Javascript
vuejs2.0实现分页组件使用$emit进行事件监听数据传递的方法
2017/02/22 Javascript
浅谈Webpack 持久化缓存实践
2018/03/22 Javascript
JavaScript类数组对象转换为数组对象的方法实例分析
2018/07/24 Javascript
Vue render渲染时间戳转时间,时间转时间戳及渲染进度条效果
2018/07/27 Javascript
微信小程序实现商品属性联动选择
2019/02/15 Javascript
JS自定义右键菜单实现代码解析
2020/07/16 Javascript
vue3.0 加载json的方法(非ajax)
2020/10/26 Javascript
JavaScript实现五子棋小游戏
2020/10/26 Javascript
ES6字符串的扩展实例
2020/12/21 Javascript
[00:36]DOTA2上海特级锦标赛 Alliance战队宣传片
2016/03/04 DOTA
[02:38]DOTA2 夜魇暗潮2020活动介绍官方视频
2020/11/04 DOTA
python模拟鼠标拖动操作的方法
2015/03/11 Python
Python numpy实现数组合并实例(vstack,hstack)
2018/01/09 Python
Python Pandas找到缺失值的位置方法
2018/04/12 Python
pandas 使用apply同时处理两列数据的方法
2018/04/20 Python
在python中利用GDAL对tif文件进行读写的方法
2018/11/29 Python
Python线上环境使用日志的及配置文件
2019/07/28 Python
Flask框架学习笔记之模板操作实例详解
2019/08/15 Python
Centos7 下安装最新的python3.8
2019/10/28 Python
Html5监听手机摇一摇事件的实现
2019/11/07 HTML / CSS
组织关系转移介绍信
2014/01/16 职场文书
保证书范文大全
2014/04/28 职场文书
小学生推普周国旗下讲话稿
2014/09/21 职场文书
教师师德师风自我剖析材料
2014/09/29 职场文书
民警群众路线教育实践活动对照检查材料
2014/10/04 职场文书
2016三八妇女节慰问信
2015/11/30 职场文书
2016年情人节广告语
2016/01/28 职场文书