浅谈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的Django框架中的QuerySets
Apr 20 Python
python操作字典类型的常用方法(推荐)
May 16 Python
python 字符串转列表 list 出现\ufeff的解决方法
Jun 22 Python
TensorFlow Session使用的两种方法小结
Jul 30 Python
PyTorch实现AlexNet示例
Jan 14 Python
Python MySQLdb 执行sql语句时的参数传递方式
Mar 04 Python
利用jupyter网页版本进行python函数查询方式
Apr 14 Python
python ETL工具 pyetl
Jun 07 Python
Python基于network模块制作电影人物关系图
Jun 19 Python
python读取excel进行遍历/xlrd模块操作
Jul 12 Python
Python连接mysql数据库及简单增删改查操作示例代码
Aug 03 Python
Python中字符串对象语法分享
Feb 24 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
使用TinyButStrong模板引擎来做WEB开发
2007/03/16 PHP
CI框架中redis缓存相关操作文件示例代码
2016/05/17 PHP
thinkphp3.2.0 setInc方法 源码全面解析
2018/01/29 PHP
laravel 实现关闭CSRF(全部关闭、部分关闭)
2019/10/21 PHP
JS网络游戏-(模拟城市webgame)提供的一些例子下载
2007/10/14 Javascript
javascript动态添加表格数据行(ASP后台数据库保存例子)
2010/05/08 Javascript
初窥JQuery(一)jquery选择符 必备知识点
2010/11/25 Javascript
JQuery live函数
2010/12/24 Javascript
juqery 学习之五 文档处理 插入
2011/02/11 Javascript
javascript文件中引用依赖的js文件的方法
2014/03/17 Javascript
理解javascript回调函数
2014/12/28 Javascript
深入学习JavaScript中的原型prototype
2015/08/13 Javascript
JavaScript中利用for循环遍历数组
2017/01/15 Javascript
Angular2环境搭建具体操作步骤(推荐)
2017/08/04 Javascript
代码详解javascript模块加载器
2018/03/04 Javascript
React Native日期时间选择组件的示例代码
2018/04/27 Javascript
微信小程序自定义键盘 内部虚拟支付
2018/12/20 Javascript
Vue的自定义组件不能使用click方法的解决
2020/07/28 Javascript
[01:03:56]Mineski vs TNC 2018国际邀请赛淘汰赛BO1 8.21
2018/08/22 DOTA
[01:44]Ti10举办地公布
2019/08/25 DOTA
在Python中使用元类的教程
2015/04/28 Python
Python 对象中的数据类型
2017/05/13 Python
解决新版Pycharm中Matplotlib图像不在弹出独立的显示窗口问题
2019/01/15 Python
详解python之heapq模块及排序操作
2019/04/04 Python
Django中URL的参数传递的实现
2019/08/04 Python
python GUI库图形界面开发之PyQt5信号与槽基础使用方法与实例
2020/03/06 Python
python中复数的共轭复数知识点总结
2020/12/06 Python
canvas 基础之图像处理的使用
2020/04/10 HTML / CSS
英国可持续奢侈品包包品牌:Elvis & Kresse
2018/08/05 全球购物
2019年Java面试必问之经典试题
2012/09/12 面试题
2014年五一劳动节社区活动总结
2014/04/14 职场文书
大学生档案自我鉴定(2篇)
2014/10/14 职场文书
运动会通讯稿300字
2015/07/20 职场文书
团结主题班会
2015/08/13 职场文书
高中班主任心得体会
2016/01/07 职场文书
Spring Cloud Netflix 套件中的负载均衡组件 Ribbon
2022/04/13 Java/Android