浅谈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使用cStringIO实现临时内存文件访问的方法
Mar 26 Python
Django实现自定义404,500页面教程
Mar 26 Python
Python实现求笛卡尔乘积的方法
Sep 16 Python
Django ORM框架的定时任务如何使用详解
Oct 19 Python
Python 对输入的数字进行排序的方法
Jun 23 Python
python的sorted用法详解
Jun 25 Python
python 杀死自身进程的实现方法
Jul 01 Python
python实现最小二乘法线性拟合
Jul 19 Python
Pyspark读取parquet数据过程解析
Mar 27 Python
pycharm中使用request和Pytest进行接口测试的方法
Jul 31 Python
Python 如何展开嵌套的序列
Aug 01 Python
python unichr函数知识点总结
Dec 16 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递归遍历多维数组实现无限分类的方法
2016/05/06 PHP
php文件操作小结(删除指定文件/获取文件夹下的文件名/读取文件夹下图片名)
2016/05/09 PHP
php实现简单的权限管理的示例代码
2017/08/25 PHP
PHP实现分布式memcache设置web集群session同步的方法
2018/04/10 PHP
利用ASP发送和接收XML数据的处理方法与代码
2007/11/13 Javascript
jQuery ui1.7 dialog只能弹出一次问题
2009/08/27 Javascript
js判断undefined变量类型使用typeof
2013/06/03 Javascript
Jquery chosen动态设置值实例介绍
2013/08/08 Javascript
js点击返回跳转到指定页面实现过程
2020/08/20 Javascript
JavaScript奇技淫巧44招【实用】
2016/12/11 Javascript
thinkjs之页面跳转同步异步操作
2017/02/05 Javascript
整理关于Bootstrap过渡动画的慕课笔记
2017/03/29 Javascript
关于vue.js过渡css类名的理解(推荐)
2017/04/10 Javascript
详解使用 Node.js 开发简单的脚手架工具
2018/06/08 Javascript
Angular 实现输入框中显示文章标签的实例代码
2018/11/07 Javascript
微信小程序控制台提示warning:Now you can provide attr "wx:key" for a "wx:for" to improve performance解决方法
2019/02/21 Javascript
angularjs实现table表格td单元格单击变输入框/可编辑状态示例
2019/02/21 Javascript
搭建一个Koa后端项目脚手架的方法步骤
2019/05/30 Javascript
微信小程序实现侧边栏分类
2019/10/21 Javascript
微信小程序动态添加和删除组件的现实
2020/02/28 Javascript
Vue自动构建发布脚本的方法示例
2020/07/24 Javascript
[50:20]DOTA2上海特级锦标赛主赛事日 - 5 总决赛Liquid VS Secret第四局
2016/03/06 DOTA
Python第三方库的安装方法总结
2016/06/06 Python
Python3匿名函数用法示例
2018/07/25 Python
python实现顺序表的简单代码
2018/09/28 Python
Tornado实现多进程/多线程的HTTP服务详解
2019/07/25 Python
django创建简单的页面响应实例教程
2019/09/06 Python
详解Python3 中的字符串格式化语法
2020/01/15 Python
python通过文本在一个图中画多条线的实例
2020/02/21 Python
python openssl模块安装及用法
2020/12/06 Python
突袭HTML5之Javascript API扩展1—Web Worker异步执行及相关概述
2013/01/31 HTML / CSS
求职信的要素有哪些呢
2013/12/26 职场文书
行政助理的岗位职责
2014/02/18 职场文书
个人承诺书怎么写
2014/05/24 职场文书
秋季校运会广播稿100字
2014/09/18 职场文书
《乙女游戏世界对路人角色很不友好》OP主题曲无字幕动画MV公开
2022/04/05 日漫