GIL:全局解释器锁
作用:保证了多个线程时,在同一时刻只有一个线程会被调用(不管电脑是几核的)(也就是说python中的线程其实是假的,这就造成在python中多进程的效率远远高于多线程,特别是多核的时候)
因此,在python中,能用进程的时候尽量用进程,而不使用线程
如果非要用线程呢?如何解决?
关键的地方用C语言来写
用死循环进行示例,通过查看各个核的占用情况(Linux中可以用htop)查看是否实现了真正的多线程
用C语言在loop.c文件中写一个死循环
void DeadLoop()
{
while(1)
{
;
}
}
并将之做成一个库
(Linux环境中)
gcc loop.c -shared -o libdeadloop.so
就会生成一个libdeadloop.so的文件(动态库)
在python文件中
from ctypes import *
from threading import Thread
#加载动态库
lib = cdl.LoadLibrary("./libdeadloop.so") #假设做制作的动态库就在当前目录下
#cdl是ctypes里面的
#创建一个子线程,让其执行C语言编写不函数,此函数是一个死循环
t = Thread(target=lib.DeadLoop) #DeadLoop是动态库里面的函数(即上面用C语言编写的函数的函数名)
t.start()
while True:
pass
#会发现两个核的占用很快就达到很高的占用
面试题
描述Ptyhon GIL的概念,以及它对python多线程的影响?多线程爬取程序是否可以比单线程快?并解释原因
参考答案:
- GIL并不是Python语言的问题,仅仅是由于历史原因在Cpython解释器(Python官网推荐)中难以移除GIL(比如java语言写的jpython就没有这个问题)。
- GIL:全局解释器锁。每个线程在执行的过程都需要先获取GIL,保证同一时刻只有一个线程可以执行代码
- 线程释放GIL锁的情况:在IO操作等可能会引起阻塞的system call之前,可以暂时释放GIL,但在执行完毕后,必须重新获取GIL。Python 3.x使用计时器(执行时间大到阀值后,当前线程释放GIL)或Python 2.x,tickets达到100
- Python使用多进程是可以利用多核的CPU资源的
- 多线程爬取比单线程性能有提升,因为遇到IO阻塞会自动释放GIL锁
如何避免GIL的问题?
- 避免使用Cpython解释器
- 用其他语言替代线程中要做的事情
GIL主要是对于计算密集型不利,对于IO密集型,用多线程(或协程)仍然能够提升性能
网友评论