Python的GIL是什么#
GIL即全局解釋器鎖(Global Interpreter Lock)
首先我認(rèn)為,Python本身語言不存在對于線程的缺陷,但是由于Python代碼不像C語言一樣經(jīng)過編譯后直接可以操作CPU,需要經(jīng)過一層解釋器解釋后才能讓CPU認(rèn)識使用。 由C語言編寫的Cpython解釋器,對于代碼中存在多個線程的程序時有限制,及解釋器只會在同一段時間處理一個線程的工作,也就是說交給CPU的任務(wù)也就是一個線程的工作。這個問題是由于當(dāng)時在設(shè)計Python的時候由于CPU還都是單核,并沒有現(xiàn)在多核的CPU,所以為了提高線程的執(zhí)行效率和CPU的使用率,就會采用解釋器一段時間只能執(zhí)行一個線程的結(jié)果。當(dāng)然并不是Python作者不去解決這個問題,而且修改GIL會帶來數(shù)據(jù)安全之類的問題:)
具體實驗如下:
1)在雙核CPU、主線程死循環(huán)的情況下
#coding=utf-8
while True:
pass
一個CPU是滿負(fù)荷運載的
2)在雙核CPU、主線程和子線程是死循環(huán)的情況下
#coding=utf-8
from threading import Thread
def test():
while True:
pass
t1 = Thread(target = test)
t1.start()
test()
我們預(yù)想一下,此種情況由于有兩個死循環(huán)線程,所以應(yīng)該是兩個CPU都滿負(fù)載運載
實際運行結(jié)果是
即兩個CPU的運行效率基本在50%,所以我們可以理解為,兩個線程任務(wù)都不是滿負(fù)載運作。這就是Python的GIL限制
解決方案#
1)首先GIL出現(xiàn)在的是Cpython解釋器中的,而Jpython解釋器中并沒有,所以說換解釋器也可以作為一種解決方案。但是這種方案有點太low,說不定對項目還有其他的影響。
2)使用進(jìn)程的方式來解決。首先Python的GIL問題是存在在線程中的,對于進(jìn)程并沒有這種限制,我們可以做以下實驗
#coding=utf-8
from multiprocessing import Process
def test():
while True:
pass
p1 = Process(target = test)
p1.start()
test()
兩個死循環(huán)進(jìn)程的運行結(jié)果是:
所以說采用進(jìn)程也是一種解決方案
3)但是過多的進(jìn)程,其實吃的資源也非常多,個人認(rèn)為最佳的解決方案是將多線程執(zhí)行的部分,換用C語言重寫,編譯完成后Python直接引入,所以說線程的工作不需要解釋器來工作,就可以極大地提高性能(當(dāng)然目前我不會寫C代碼)