浅谈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 相关文章推荐
Django中利用filter与simple_tag为前端自定义函数的实现方法
Jun 15 Python
linux环境下的python安装过程图解(含setuptools)
Nov 22 Python
Django中使用session保持用户登陆连接的例子
Aug 06 Python
Python中正反斜杠(‘/’和‘\’)的意义与用法
Aug 12 Python
Python pandas实现excel工作表合并功能详解
Aug 29 Python
Python高级编程之消息队列(Queue)与进程池(Pool)实例详解
Nov 01 Python
Python常用模块os.path之文件及路径操作方法
Dec 03 Python
Pandas实现一列数据分隔为两列
May 18 Python
pycharm sciview的图片另存为操作
Jun 01 Python
Matplotlib 折线图plot()所有用法详解
Jul 28 Python
Python利用zhdate模块实现农历日期处理
Mar 31 Python
利用Python实现模拟登录知乎
May 25 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自动识别字符集并完成转码详解
2013/08/02 PHP
Yii2前后台分离及migrate使用(七)
2016/05/04 PHP
php如何修改SESSION的生存存储时间的实例代码
2017/07/05 PHP
PHP实现求两个字符串最长公共子串的方法示例
2017/11/17 PHP
PHP使用PDO 连接与连接管理操作实例分析
2020/04/21 PHP
JavaScript 事件冒泡简介及应用
2010/01/11 Javascript
在jQuery 1.5中使用deferred对象的代码(翻译)
2011/03/10 Javascript
用jquery方法操作radio使其默认选项是否
2013/09/10 Javascript
详解JavaScript中的事件流和事件处理程序
2016/05/20 Javascript
AngularJS表格详解及示例代码
2016/08/17 Javascript
jQuery实现点击后高亮背景固定显示的菜单效果【附demo源码下载】
2016/09/21 Javascript
AngularJS实现在ng-Options加上index的解决方法
2016/11/03 Javascript
smartupload实现文件上传时获取表单数据(推荐)
2016/12/12 Javascript
AngularJS 限定$scope的范围实例详解
2017/06/23 Javascript
浅谈Vue.js应用的四种AJAX请求数据模式
2017/08/30 Javascript
vue项目中使用百度地图的方法
2018/06/08 Javascript
cordova+vue+webapp使用html5获取地理位置的方法
2019/07/06 Javascript
Vue中使用better-scroll实现轮播图组件
2020/03/07 Javascript
详解vue中在循环中使用@mouseenter 和 @mouseleave事件闪烁问题解决方法
2020/04/07 Javascript
原生小程序封装跑马灯效果
2020/10/21 Javascript
跟老齐学Python之编写类之四再论继承
2014/10/11 Python
在Python中操作日期和时间之gmtime()方法的使用
2015/05/22 Python
python实现将html表格转换成CSV文件的方法
2015/06/28 Python
python使用arcpy.mapping模块批量出图
2017/03/06 Python
Python调用C# Com dll组件实战教程
2017/10/12 Python
Python操作Sql Server 2008数据库的方法详解
2018/05/17 Python
python单例模式实例解析
2018/08/28 Python
python离线安装外部依赖包的实现
2020/02/13 Python
keras输出预测值和真实值方式
2020/06/27 Python
优衣库美国官网:UNIQLO美国
2018/04/14 全球购物
解释下面关于J2EE的名词
2013/11/15 面试题
自我鉴定怎么写
2013/12/05 职场文书
护士求职自荐信范文
2014/03/19 职场文书
付款委托书范本
2014/10/05 职场文书
私用公车造成事故检讨书
2014/11/16 职场文书
2016年优秀党员教师先进事迹材料
2016/02/29 职场文书