测试环境 Ubuntu 16.04,先查看CPU信息,这是一台双核CPU机器
对比测试,先来个Java版本
安装 java
启动两个线程,线程中做一个死循环
vi Test.java
编译并执行
再开一个终端,在top中按1查看CPU使用情况,两个CPU全速运行,如下图
安装Python3
编写如下代码,work中也是死循环
vi test.py
执行python代码,你会发现python的多线程,在同一时刻,只能利用一个CPU资源,所以两颗CPU交替执行,各占用50%,如下图
因为Python中为了线程安全,有全局解释器锁(GIL),所以不能很好的利用多核CPU。下面来做一个线程安全测试,先来Java版本
多执行几次, 结果如下,可见线程是不安全的:
再来Python版本
多次执行,结果如下
是不是傻眼了,Python中有GIL,同样不是线程安全!既然如此,GIL的存在,又有什么用呢? 下面继续分析
下面继续分析
重点看前面4条指令
将 i 值加载到堆栈上
将常数 1 加载到堆栈上
将堆栈顶部的两个值相加
将结果存储回 i
我们写的一行代码 ,被编译成多个指令进行操作,GIL仅能保证字节码(bytecode)线程安全,刚才的 操作,并非原子操作,所以出现了线程安全问题,下面来看一个原子操作函数
这一次,核心代码是前3行
将 arr 值加载到堆栈上
将排序方法加载到堆栈上
调用排序方法
由于操作是原子的,没有机会在执行时,被中断,所以是线程安全的
我们看起来, 似乎比 函数简单,但不是原子操作
尽管Pyton中有 GIL,在编写多线程时,我们仍然要自行加锁来保证线程安全。
最后来个线程安全版本
执行结果如下
更多锁相关操作
刚才的代码,也可以写成下面这样
Python中的多线程到底是不是鸡肋,心中有数了吧?
多代码情况下,公众号后台真难排版用手机看同童鞋辛苦了,切到电脑上看吧!
关注作者
领取专属 10元无门槛券
私享最新 技术干货