浅谈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实现斐波那契递归函数的方法
Sep 08 Python
Python编程之多态用法实例详解
May 19 Python
详细介绍Python的鸭子类型
Sep 12 Python
详解python使用Nginx和uWSGI来运行Python应用
Jan 09 Python
从django的中间件直接返回请求的方法
May 30 Python
flask框架视图函数用法示例
Jul 19 Python
Python2和Python3之间的str处理方式导致乱码的讲解
Jan 03 Python
简单了解python的break、continue、pass
Jul 08 Python
在PyCharm中实现添加快捷模块
Feb 12 Python
基于Python和C++实现删除链表的节点
Jul 06 Python
python中re模块知识点总结
Jan 17 Python
matplotlib部件之套索Lasso的使用
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
php安全之直接用$获取值而不$_GET 字符转义
2012/06/03 PHP
PHP+FFMPEG实现将视频自动转码成H264标准Mp4文件
2014/09/24 PHP
Yii基于CActiveForm的Ajax数据验证用法示例
2016/07/14 PHP
JS小框架 fly javascript framework
2009/11/26 Javascript
基于JQuery实现异步刷新的代码(转载)
2011/03/29 Javascript
Javascript生成全局唯一标识符(GUID,UUID)的方法
2016/02/27 Javascript
BootStrap智能表单实战系列(十一)级联下拉的支持
2016/06/13 Javascript
JS去除空格和换行的正则表达式(推荐)
2016/06/14 Javascript
使用JS实现图片展示瀑布流效果(简单实例)
2016/09/06 Javascript
vue的props实现子组件随父组件一起变化
2016/10/27 Javascript
基于Javascript实现的不重复ID的生成器
2016/12/25 Javascript
JavaScript中利用for循环遍历数组
2017/01/15 Javascript
使用Node.js实现简易MVC框架的方法
2017/08/07 Javascript
详解A标签中href=""的几种用法
2017/08/20 Javascript
vue下跨域设置的相关介绍
2017/08/26 Javascript
vue项目使用$router.go(-1)返回时刷新原来的界面操作
2020/07/26 Javascript
[04:56]经典回顾:前Ehome 与 前LGD
2015/02/26 DOTA
python实现udp数据报传输的方法
2014/09/26 Python
Python中用于转换字母为小写的lower()方法使用简介
2015/05/19 Python
Python中用字符串调用函数或方法示例代码
2017/08/04 Python
python中将函数赋值给变量时需要注意的一些问题
2017/08/18 Python
浅谈Python对内存的使用(深浅拷贝)
2018/01/17 Python
详解django中url路由配置及渲染方式
2019/02/25 Python
在python中,使用scatter绘制散点图的实例
2019/07/03 Python
Python人工智能之路 之PyAudio 实现录音 自动化交互实现问答
2019/08/13 Python
python 表格打印代码实例解析
2019/10/12 Python
学python需要去培训机构吗
2020/07/01 Python
Python使用Turtle模块绘制国旗的方法示例
2021/02/28 Python
利用css3画个同心圆示例代码
2017/07/03 HTML / CSS
凯特方迪化妆品官网:Kat Von D Beauty
2016/11/15 全球购物
System.Array.CopyTo()和System.Array.Clone()有什么区别
2016/06/20 面试题
竞选文艺委员演讲稿
2014/04/28 职场文书
十佳标兵事迹材料
2014/08/18 职场文书
工厂门卫岗位职责
2015/04/13 职场文书
追讨欠款律师函
2015/06/24 职场文书
Golang二维数组的使用方式
2021/05/28 Golang