python C 解释器有一个叫GIL 的东西作用:
每个线程在执行的过程都需要先获取GIL,保证同一时刻只有一个线程可以执行代码。
所以在python中,如果对于CPU密集型任务,多线程是没有用的,因为一个线程不会释放GIL;但是对于IO密集型任务,多线程还是能提高效率,因为在IO阻塞的情况下,会自动释放GIL锁。
为什么不移除GIL
Guido的声明:http://www.artima.com/forums/flat.jsp?forum=106&thread=214235
所以对于python GIL 的问题解决方案有几种
- 不用C解释器,用JAVA解释器
- 用多进程
- 调用C代码
为什么调用C代码能够解决GIL 问题?
个人理解,gcc 编译的c语言执行文件或者动态库,已经是二进制文件,二进制文件可以直接被机器识别,直接调用,不走C解释器,也就不存在GIL这一说了。
测试GIL 问题
测试代码链接: 测试代码
单线程测试
while True :
pass
表现:基本占满1个核
2个线程测试
import threading
def test():
while True:
pass
#子线程
threading.Thread(target=test).start()
#主线程
while True:
pass
表现:仍然只占满一个核
2个进程测试
import multiprocessing
def test():
while True:
pass
#子进程
multiprocessing.Process(target=test).start()
#主进程
while True:
pass
表现 :占满了2个核
通过C语言来实现
C代码
//动态库编译
//gcc deadloop.c -shared -o libloop.so
void test(){
while(1);
}
==================================
python 中调用
from ctypes import cdll
from threading import Thread
lib = cdll.LoadLibrary("./libloop.so")
Thread(target=lib.test).start()
while True:
pass
============================
表现:占满2个核