浅谈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原始字符串(raw strings)用法实例
Oct 13 Python
Python实现字典的key和values的交换
Aug 04 Python
python爬虫的工作原理
Mar 05 Python
Django 开发调试工具 Django-debug-toolbar使用详解
Jul 23 Python
pycharm配置git(图文教程)
Aug 16 Python
Python实现转换图片背景颜色代码
Apr 30 Python
使用pymysql查询数据库,把结果保存为列表并获取指定元素下标实例
May 15 Python
使用keras实现非线性回归(两种加激活函数的方式)
Jul 05 Python
Python+pyftpdlib实现局域网文件互传
Aug 24 Python
Python pip install之SSL异常处理操作
Sep 03 Python
pycharm 实现光标快速移动到括号外或行尾的操作
Feb 05 Python
python利用proxybroker构建爬虫免费IP代理池的实现
Feb 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中路径问题的解决方案
2006/10/09 PHP
php中将地址生成迅雷快车旋风链接的代码[测试通过]
2011/04/20 PHP
ThinkPHP与PHPExcel冲突解决方法
2011/08/08 PHP
php教程之魔术方法的使用示例(php魔术函数)
2014/02/12 PHP
阿里云的WindowsServer2016上部署php+apache
2018/07/17 PHP
使用jquery为table动态添加行的实现代码
2011/03/30 Javascript
JavaScript面向对象程序设计三 原型模式(上)
2011/12/21 Javascript
JavaScript可否多线程? 深入理解JavaScript定时机制
2012/05/23 Javascript
Json字符串转换为JS对象的高效方法实例
2013/05/01 Javascript
JavaScript定义类和对象的方法
2014/11/26 Javascript
Nodejs实现的一个静态服务器实例
2014/12/06 NodeJs
jQuery 判断图片是否加载完成方法汇总
2015/08/10 Javascript
javascript实现网页中涉及的简易运动(改变宽高、透明度、位置)
2015/11/29 Javascript
javascript禁止超链接跳转的方法
2016/02/02 Javascript
Bootstrap轮播图的使用和理解4
2016/12/14 Javascript
JS实现侧边栏鼠标经过弹出框+缓冲效果
2017/03/29 Javascript
基于Ionic3实现选项卡切换并重新加载echarts
2020/09/24 Javascript
python中如何使用正则表达式的非贪婪模式示例
2017/10/09 Python
python 寻找优化使成本函数最小的最优解的方法
2017/12/28 Python
python3+PyQt5+Qt Designer实现扩展对话框
2018/04/20 Python
用python脚本24小时刷浏览器的访问量方法
2018/12/07 Python
Python一行代码实现快速排序的方法
2019/04/30 Python
Python批量查询关键词微信指数实例方法
2019/06/27 Python
pytorch cuda上tensor的定义 以及减少cpu的操作详解
2020/06/23 Python
Python爬取数据并实现可视化代码解析
2020/08/12 Python
Python中logging日志的四个等级和使用
2020/11/17 Python
英国最大的自有市场,比亚马逊便宜:Flubit
2019/03/19 全球购物
Blue Nile蓝色尼罗河香港官网:世界最大在线钻石珠宝销售商
2020/05/07 全球购物
在子网210.27.48.21/30种有多少个可用地址?分别是什么?
2014/07/27 面试题
技能比武方案
2014/05/21 职场文书
我心目中的好老师活动方案
2014/08/19 职场文书
2014年小学教学工作总结
2014/11/13 职场文书
模范教师材料大全
2014/12/16 职场文书
安徽导游词
2015/02/12 职场文书
工作转正自我鉴定范文
2019/06/21 职场文书
python正则表达式re.search()的基本使用教程
2021/05/21 Python