浅谈Python的GIL机制

python多线程

实验:

  • 开启两个线程
  • 一个线程sleep 4s 死循环打印
  • 另外一个线程sleep 1s 死循环打印

结果:会正常的交替运行
结论:一个线程被阻塞的时候,CPU会被释放,然后另外一个线程被执行。。

使用python为例子

参考资料:

[http://zhuoqiang.me/python-thread-gil-and-ctypes.html](http://zhuoqiang.me/python-thread-gil-and-ctypes.html)

所有Thread的PID都与主程序相同,而每个Process都有一个不同的PID要

单线程

使用如下的代码:

#!coding=utf8
"""
使用多核
"""
import sys
sys.path.append('../../')

if __name__ == "__main__":
   print("start run here")
   while True:
       a = 4 / 34.0
   print('end run here')

开始运行前


image.png

使用
python expmultiprocess.py

开始运行后


image.png

可以看出,占满一个核心的所有资源了。

主线程外再开启一个线程


image.png

可以看出:

  1. 有两个进程号。PID是不一样的。
  2. 所有的CPU并没有占満

因为GIL的原因:

  1. 单进程单线程可以占用并占满一个核心。
  2. 单进程多线程可以占用多核心但无法占满,只会分时复用。

GIL全局解释器锁

参考资料:http://zhuoqiang.me/python-thread-gil-and-ctypes.html

GIL 的全程为 Global Interpreter Lock ,意即全局解释器锁。
在 Python 语言的主流实现 CPython 中,GIL 是一个货真价实的全局线程锁,在解释器解释执行任何 Python 代码时,都需要先获得这把锁才行,在遇到 I/O 操作时会释放这把锁。如果是纯计算的程序,没有 I/O 操作,解释器会每隔 100 次操作就释放这把锁,让别的线程有机会执行,这个次数可以通过sys.setcheckinterval。
所以虽然 CPython 的线程库直接封装操作系统的原生线程,但 CPython 进程做为一个整体,同一时间只会有一个获得了 GIL 的线程在跑,其它的线程都处于等待状态等着 GIL 的释放。这也就解释了我们上面的实验结果:虽然有两个死循环的线程,而且有两个物理 CPU 内核,但因为 GIL 的限制,两个线程只是做着分时切换,总的 CPU 占用率还略低于 50%。

以java为例子

Java的多线程是完全可以把多个核心跑满的。

package com.data;

public class ThreadDemo extends Thread {

public ThreadDemo() {

}

public void run() {

while (true) {

continue;

}

}

public static void main(String[] args) {

try {

ThreadDemo h1 = new ThreadDemo();

h1.start();

ThreadDemo h2 = new ThreadDemo();

h2.start();

ThreadDemo h3 = new ThreadDemo();

h3.start();

h1.join();

h2.join();

h3.join();

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

}

里面开启了三个线程,然后CPU三个核心都跑满了。

image.png

使用pyspark运行

Python可以通过一些专门的数据处理框架来实现高效利用CPU,直接所有的核心都利用起来了。不用自己再去写并行计算的内容结构了。

image.png
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 一. 操作系统概念 操作系统位于底层硬件与应用软件之间的一层.工作方式: 向下管理硬件,向上提供接口.操作系统进行...
    月亮是我踢弯得阅读 11,228评论 3 28
  • 必备的理论基础 1.操作系统作用: 隐藏丑陋复杂的硬件接口,提供良好的抽象接口。 管理调度进程,并将多个进程对硬件...
    drfung阅读 8,981评论 0 5
  • 转一篇关于Python GIL的文章。归纳一下,CPU的大规模电路设计基本已经到了物理意义的尽头,所有厂商们都开始...
    SeanCheney阅读 13,813评论 0 12
  • 前言:博主在刚接触Python的时候时常听到GIL这个词,并且发现这个词经常和Python无法高效的实现多线程划上...
    whypro阅读 4,900评论 0 1
  • 早上醒来看看那初生的骄阳, 心灵被朝气滋养。 忘却了昨夜难眠的烦恼, 给自己打气, 今日是完美的一天! 我能行! ...
    醉梦客阅读 1,306评论 0 3

友情链接更多精彩内容