A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© Jahanxu 初级黑马   /  2019-4-20 12:25  /  2699 人查看  /  0 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 Jahanxu 于 2019-4-20 13:38 编辑

GIL是什么        
GIL百度解释:全局解释器锁(Global Interpreter Lock)是计算机程序设计语言解释器用于同步线程的工具,使得在同一进程内任何时刻仅有一个线程在执行。常见例子有CPython(JPython不使用GIL)与 Ruby MRI (也称作 CRuby,Ruby语言解释器)

我们在开发一个大型的应用程序时,为了提高程序的执行效率。让程序能最优的利用电脑的资源,往往会用多进程或者多线程的方式来实现。但是多进程和多线程在使用时也各有优缺点,以下是两者对比:
关系对比:
  - 线程依附进程,有进程才有线程
  - 一个进程至少有一个线程,也可以开辟多个线程
区别对比:
  - 线程可以共享全局变量,主要资源竞争问题,**解决办法**:互斥锁和线程同步
  - 进程不可以共享全局变量, 进程比线程更稳定, 进程资源开销大于线程
  - 进程是**操作系统资源分配的基本单位**,线程是**CPU调度的基本单位**
  - 线程不能独立存在,必须依附于进程
优缺点对比:
  - 进程:
    - 优点:稳定性高,可以使用多核资源
    - 缺点:资源开销大
  - 线程:
    - 优点:资源开销小
    - 缺点:不能使用多核资源,稳定性低于进程

根据上面的对比可以知道只有多线程才会存在GIL的问题,这个问题产生的核心原因就是:资源共享


进程和线程选择
我们在设计一个程序的时候什么时候设计成多进程模式,什么时候设计成多线程模式,那我们就要知道多线程其实因为GIL的原因导致了同一时间只有一个线程能被CPU调度。只是由于时间是毫秒级的,给我们的表象就好像同一时间多个线程都在运行。
那这两种模式怎么选择呢,下面介绍一下两个概念:

计算密集型:每个请求的命令中,大都包含不同的参数值,很难重用前一次计算的结果,所以要按照约定的业务逻辑重新计算,并按照约定的格式返回数据,且计算在总耗时中占比较大。

IO密集型:指的是系统的CPU性能相对硬盘、内存要好很多,此时,系统运作,大部分的状况是CPU在等I/O (硬盘/内存) 的读/写操作,此时CPU Loading并不高。

通过比较知道计算密集型需要很高的CPU占用率,一直进行计算操作;而IO密集型则把大量的时间花在了输入输出上面,而数据的从发送到接收会有一段时间(对于我们来说很短),就好比我发送一个数据从发送出去到接收耗时5s,我需要发送三次,若用单线程则需要15s;假如使用多线程,在第一次发出去之后,接着发第二次,再接着发第三次,因为返回数据需要时间所以为了不让第一个线程在等待状态浪费CPU资源,CPU释放掉第一次的发送,调第二次的发送线程,第三次同理。

总结:
计算密集型:用进程设计
IO密集型:用线程或者Python特有的协程

再回过头来说GIL的问题,由于GIL是历史遗留问题,在CPython(C语言写的Python解释器)中难以移除,那为了提高CPU的利用率不想使用GIL,有两种办法:
1、更换Python解释器
     PyPy:PyPy是另一个Python解释器,它的目标是执行速度,PyPy采用JIT技术,对Python代码进行动态编译,所以可以显著提高Python代码的执行速度。
     Jython:Jython是运行在Java平台上的Python解释器,可以直接把Python代码编译成Java字节码执行。
2、核心代码更换其他语言实现
    用到多线程的地方可以用其他代码来实现,作为Python的链接库,这就是Python语言的强大之处。


20190419233850596.png (53.1 KB, 下载次数: 39)

20190419233850596.png

0 个回复

您需要登录后才可以回帖 登录 | 加入黑马