尹立博:Python 全局解释器锁与并发 | AI 研习社第 59 期猿桌会
原标题:尹立博:Python 全局解释器锁与并发 | AI 研习社第 59 期猿桌会
雷锋网 AI 科技评论按:作为排名靠前的最受欢迎和增长最快的编程语言之一,Python 是一种多用途、高级别、面向对象、交互式、解释型和对用户非常友好的编程语言,拥有卓越的可读性和极高的自由度。而为了能利用多核多线程的的优势,同时又要保证线程之间数据完整性和状态同步,Python 官方的、最广泛使用的解释器——CPython 往往会采取最简单的加锁的方式——全局解释器锁(GIL)。
然而,GIL 的设计有时会显得笨拙低效,并对语言的并发性带来严重限制,但是此时由于内置库和第三方库已经对 GIL 形成了巨大的依赖,想改变 GIL 反而变得困难了。不过实际上,Python 生态系统中存在诸多工具可以解决这一问题。
近日,在雷锋网 AI 研习社公开课上,毕业于澳大利亚国立大学的尹立博介绍了全局解释器锁(GIL)和提升并发性的不同思路。公开课回放视频网址:?=aitechtalkyinlibo
尹立博:毕业于西澳大利亚大学和澳大利亚国立大学。现在堪培拉 Seeing Machines 公司担任数据分析师,日常使用 Python 数据工具对大量时序数据进行管理、分析与可视化开发。
分享主题:Python 全局解释器锁与并发
分享提纲:
1、全局解释器锁 (GIL)
2、多进程 (multiprocessing)
3、多线程 (multithreading)
4、异步 (async)
5、分布式计算(以 Dask 为例)
雷锋网 AI 研习社将其分享内容整理如下:
今天要跟大家分享的是 Python 全局解释器锁与并发。我会先介绍一下全局解释器锁 (GIL))的概念和影响;接下来会借助几个案例分析来展示 Python 通过多进程、多线程和异步、分布式计算来达成并发的几种方式;最后会介绍一套分布式计算工具——Dask。
全局解释器锁 (GIL)
GIL 的概念用简单的一句话来解释,就是「任一时刻,无论线程多少,单一 CPython 解释器只能执行一条字节码」。这个定义需要注意的点包括:
第一,GIL 不属于 Python 语言定义,而是 CPython 解释器实现的一部分;
第二,其他 Python 解释器不一定有 GIL。例如 Jython (JVM) 和 IronPython (CLR) 没有 GIL,而 PyPy 有 GIL;
第三,GIL 并不是 Python 的专利。其他语言也有 GIL,尤其是动态语言,如 Ruby MRI。
说到 GIL,就不得不提 Python 线程模型,它的运行方式如下:
CPython 使用 OS 原生线程,由 OS 负责调度;
每个解释器进程有唯一的主线程和用户定义的任意数量子线程;
GIL 是字节码层面上的互斥锁。刚刚定义中提到的 PyThread_type_lock 就是 OS 互斥锁的别名
每个解释器进程有且仅有一把锁;
当解释器启动时,主线程即获取 GIL;
一个线程持有 GIL 并执行字节码时,其他线程处于阻塞状态。
GIL 被加到 CPython 解释器中,是有其原因的。在 1992 年,单 CPU 是合理的假设!多核则是 2005-2006 年前后才普及,此外,GIL 的优势还包括:
简化解释器实现;
优化单进程性能;
简化 C 扩展库的整合。
Python 有两种多任务模型:一种叫做协作式 (cooperative) 多任务;另一种叫抢占式 (preemptive) 多任务。
协作式多任务:
在 I/O 前主动释放 GIL,I/O 之后重新获取。这可以在 C 源代码中使用 Py_BEGIN_ALLOW_THREADS / Py_END_ALLOW_THREADS 宏实现
这种多任务方式能够提升代码性能!
抢占式多任务:
间歇性挂起活跃进程,交由 OS 重新调度
Python 2:每执行 100 个字节码,当前进程就会被挂起
Python 3.2+: 每隔 5 毫秒
这种多任务方式不提高代码性能,但使得多个任务能在同一时间段内执行
接下来可以进展到去除 GIL。这是很多 Python 用户十分期待的事情,但是短期内是不太可能实现的,它的难点包括:
第一,技术问题
Guido 要求不降低单线程执行效率
兼容现有引用计数与垃圾回收机制
兼容现有 C 扩展
第二,在社区友好性上,不显著提高开发难度。
尽管如此,我们也可以看到一些现有去除 GIL 的实验性的方案:
Gilectomy:尝试将 GIL 换成若干小锁,然而这种方案严重降低了 Python 的性能。首先,它会使得多线程竞争同一把锁。其次,它在将 GIL 换成若干小锁后,将严重降低缓存的命中率。
PyPy:实验性分支支持软件事务内存 (STM),不过 STM 目前还是一个相对少见的机制,可解决当前很多问题,但是实现非常困难——尤其在像 Python 这种高度动态的语言当中。
Starlark:这种方案并非去掉 GIL,而是一门兼容部分 Python 语法,并发执行字节码的新语言。它目前用于 Google Bazel 编译系统,我个人认为这是一个非常有意思的未来趋势。
版权保护: 本文由 沃派博客-沃派网 编辑,转载请保留链接: http://www.bdice.cn/html/8523.html
- 上一篇:大淘金,瞄准最后一波人口红利
- 下一篇:康佳如何在“电视寒冬”下成功突围?