概述GIL(全局解释器锁) 以及 解决GIL带来的影响的第二种方法时python 子线程调用 C语言方法

GIL(全局解释器锁) 以及 python子线程调用C语言的方法

今天偶然间看到一篇文章,关于 GIL 在python中对 计算密集型 多任务的影响。
接下来,我来尝试分析一下 GIL 到底是什么,怎么去解决 GIL 带来的问题,以及在解决问题的第二种方法时说明怎样调用其它语言的方法。

  • 问题一:什么是 GIL?
  • 问题二:线程释放GIL的情况是什么?
  • 问题三:怎么解决 GIL 带来的影响?

问题一: 什么是 GIL ?

首先,GIL 中文全称叫做——全局解释器锁,我们先不管别的,光看名字就知道,肯定和 解释器有关,对 没错,GIL 就是 实现python解释器(Cpython)的时候引入的一个概念,是Cpython(C语言写的python解释器)的特性,GIL 和python这个语言,没有半点关系,是cpython解释器(历史遗留问题造成的,也就是说,你用Cpython解释器(ubantu自带的python解释器)面临GIL 问题,但是你用Jpython解释器(JAVA写的python解释器)就没有任何问题。
其次,GIL 的作用:保证了 系统在执行代码的时候,同一时刻只能执行一个线程,这就导致了当用python实现多线程的时候,每个线程在使用之前,先获得一个GIL锁,最终导致 其实实现的多任务并不是真正的多任务,而是假的多任务(并发)。造成了什么影响呢?就是当你调用多线程的时候体现不出 多核CPU的优点,因为 GIL 保证了同一时刻只能有一个线程在执行。

问题二:线程释放GIL的情况是什么?

【1】当程序执行到 IO(读写操作) 以及其他可能会引起堵塞的系统调用操作(system call)之前,线程可 暂时 释放GIL锁,执行完毕之后,又会立刻重新获取GIL锁。
【2】Python3.x使用计时器(执行时间达到阈值后,当前线也会程释放GIL)

问题三:怎么解决 GIL 带来的影响?

【1】换一个python解释器,不用Cpython解释器(即不用python官网上下载的解释器了),改为用Jpython解释器
【2】用其它语言代替实现(比如说C语言——这里用C语言演示)

//**实验**

// 【1】首先,创建一个C程序文件—— loop.c,简单的死循环用来测试 CPU占用情况
void DeadLoop()
{
	while(1)
	{
		;
	}
}

// 【2】把这个C程序文件转为 动态库
// Linux中转为动态库的命令: gcc -loop.c -shared -o llibdead_loop.so
gcc -loop.c -shared -o llibdead_loop.so

//创建 01.py python文件
from ctypes import *
from threading import Thread
# 加载动态库
lib = cdll.LoadLibrary("./libdead_loop.so")
# 创建一个子线程,让它执行C语言编写的函数
t = Thread(target=lib.DeadLoop)
t.start()
# 主线程
while True:
	pass

无论怎样,多线程还是要比单线程效率高的,因为单线程 需要等待某一任务完成之后再去进行下一个任务,如果期间遇到堵塞,有可能等很长时间,而多线程就算有GIL的影响,当遇到堵塞的时候,就会利用这个堵塞的时间去完成其他任务,效率也是快了很多的。

发布了36 篇原创文章 · 获赞 75 · 访问量 5464

猜你喜欢

转载自blog.csdn.net/weixin_44449518/article/details/97136791