并发编程(三)Python编程慢的罪魁祸首。全局解释器锁GIL
并发编程(四)如何使用多线程,使用多线程对爬虫程序进行修改及比较
并发编程(七)好用的线程池ThreadPoolExecutor
并发编程(九)使用多进程multiprocessing加速程序运行
并发编程(十二)使用subprocess启动电脑任意程序(听歌、解压缩、自动下载等等)
Python速度慢的两大原因
-
在介绍python速度慢的原因之前,先来看看python速度有多慢以及现状。
- 相比C/C++/JAVA,Python确实慢,甚至在一些特殊场景下,Python比C++慢100~200倍。
- 现状:
- 由于速度慢的原因,许多公司的基础架构代码都是用C/C++来开发实现的。
- 比如推荐引擎、搜索引擎、存储引擎等。
-
具体原因:
-
python是动态类型语言,边解释边执行。
-
CIL,导致Python无法利用多核CPU并发执行。
-
GIL是什么?
-
全局解释器锁(Global Interpreter Lock,简称GIL)
-
是计算机程序设计语言解释器用于同步线程的一种机制,它使得任何时刻仅有一个线程在执行。
-
即使在多核处理器上,使用GIL的解释器也只允许同一时间执行一个线程。
-
(注:上图来源以下网站http://www.dabeaz.com/python/UnderstandingGIL.pdf)
-
根据上图可以看出由于GIL的存在,即使电脑有多核CPU,单个时刻也只能使用一个,所以相比并发加速的C/C++/JAVA来就就会慢。
为什么存在GIL?
-
简而言之:Python设计初期,为了规避并发问题引入了GIL,现在想去除却去不掉了。
-
那么当初为什么要引入GIL呢?
-
为了解决多线程之间数据完整性和状态同步问题。
-
详解:
-
Python中对象的管理,是使用引用计数器进行的,引用数为0则释放对象。
-
示例:
- 假如线程A和线程B都引用了对象obj,obj.ref_num=2,如果此时线程A和B都想撤销对obj的引用,就会出现下图情况。
-
在这个情况下呢,Python引入了GIL,解决了该类问题,简化了Python对共享资源的管理。
-
怎么样规避GIL带来的限制?
- 多线程Threading机制依然是有用的,用于IO密集型计算。
- 因为在IO期间,线程会释放GIL,实现CPU和IO的并行,因此多线程用于IO密集型计算依然可以大幅提升速度。
- 但是多线程用于CPU密集型计算时,只会更加拖慢速度。
- 为了应对GIL,python提供了multiprocessing模块,使用multiprocessing的多进程机制实现并行计算、利用多核CPU优势
提供了multiprocessing模块,使用multiprocessing的多进程机制实现并行计算、利用多核CPU优势