浅谈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中生成器用法
Dec 20 Python
关于python列表增加元素的三种操作方法
Aug 22 Python
python实现机器学习之多元线性回归
Sep 06 Python
django 使用全局搜索功能的实例详解
Jul 18 Python
如何在Cloud Studio上执行Python代码?
Aug 09 Python
Python多进程编程常用方法解析
Mar 26 Python
JAVA及PYTHON质数计算代码对比解析
Jun 10 Python
django filter过滤器实现显示某个类型指定字段不同值方式
Jul 16 Python
Python字符串三种格式化输出
Sep 17 Python
matplotlib部件之套索Lasso的使用
Feb 24 Python
教你用Python写一个植物大战僵尸小游戏
Apr 25 Python
Python制作表白爱心合集
Jan 22 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 xfocus防注入资料
2008/04/27 PHP
如何使用PHP给图片加水印
2016/10/12 PHP
php使用高斯算法实现图片的模糊处理功能示例
2016/11/11 PHP
用cssText批量修改样式
2009/08/29 Javascript
javascript 控制 html元素 显示/隐藏实现代码
2009/09/01 Javascript
Javascript面象对象成员、共享成员变量实验
2010/11/19 Javascript
jQuery插件animateSlide制作多点滑动幻灯片
2015/06/11 Javascript
jQuery实现滚动切换的tab选项卡效果代码
2015/08/26 Javascript
不用一句js代码初始化组件
2016/01/27 Javascript
JS实现点击登录弹出窗口同时背景色渐变动画效果
2016/03/25 Javascript
javascript 删除数组元素和清空数组的简单方法
2017/02/24 Javascript
jQuery+Ajax实现用户名重名实时检测
2017/06/01 jQuery
IntersectionObserver实现图片懒加载的示例
2017/09/29 Javascript
使用原生js封装的ajax实例(兼容jsonp)
2017/10/12 Javascript
vue页面切换到滚动页面显示顶部的实例
2018/03/13 Javascript
jQuery实现参数自定义的文字跑马灯效果
2018/08/15 jQuery
微信小程序自定义导航教程(兼容各种手机)
2018/12/12 Javascript
js计算两个时间差 天 时 分 秒 毫秒的代码
2019/05/21 Javascript
微信小程序通过一个json实现分享朋友圈图片
2019/09/03 Javascript
TypeScript中使用getElementXXX()的示例代码
2019/09/12 Javascript
vue3修改link标签默认icon无效问题详解
2019/10/09 Javascript
vue中后端做Excel导出功能返回数据流前端的处理操作
2020/09/08 Javascript
python自动格式化json文件的方法
2015/03/11 Python
python下载图片实现方法(超简单)
2017/07/21 Python
python numpy 部分排序 寻找最大的前几个数的方法
2018/06/27 Python
Python实现性能自动化测试竟然如此简单
2019/07/30 Python
Python解析多帧dicom数据详解
2020/01/13 Python
Python并发爬虫常用实现方法解析
2020/11/19 Python
python解包用法详解
2021/02/17 Python
咖啡为什么会有酸味?你喝到的咖啡為什麼是酸的?
2021/03/17 冲泡冲煮
No7 Beauty美国官网:英国国民护肤品牌
2019/10/31 全球购物
日本最大的彩色隐形眼镜销售网站:CharmColor
2020/09/09 全球购物
工作失职检讨书(精华篇)
2014/10/15 职场文书
捐助倡议书
2015/01/19 职场文书
学困生转化工作总结
2015/08/13 职场文书
spring 项目实现限流方法示例
2022/07/15 Java/Android