Python GIL(Global Interpreter Lock) 解釋器鎖
GIL本質就是一把互斥鎖溺欧,將并發(fā)變成串行官还,以此來控制同一時間共享數(shù)據(jù)只能被一個任務所修改,進而保證數(shù)據(jù)的安全性。在Cpython解釋器中剥槐,同一個進程下開啟多線程慨灭,同一時刻只能有一個線程執(zhí)行朦乏,無法利用多核優(yōu)勢。GIL并不是Python的特性氧骤,Python完全可以不依賴于GIL呻疹。
線程互斥鎖的示例:
from threading import Thread, Lock
import time
n = 100
def task():
global n
with mutex: # 獲取鎖 相當于 mutex.acquire() 和 mutex.release()
temp = n
time.sleep(0.1)
n = temp - 1
if __name__ == '__main__':
starttime = time.time()
mutex = Lock() # 生成一個鎖對象
t_l = []
for i in range(100):
t = Thread(target=task)
t_l.append(t)
t.start()
for t in t_l:
t.join()
stoptime = time.time()
print('主線程 %s ' % n)
print('run time is %s' % (stoptime - starttime))
輸出結果:
主線程 0
run time is 10.062247514724731
如果不加鎖,則出現(xiàn)如下結果:
主線程 99
run time is 0.11712527275085449
- CPU是用來做計算的筹陵,在I/O密集性的任務下刽锤,并不能發(fā)揮CPU的多核優(yōu)勢镊尺,反而使用線程開銷更小,任務處理更快并思。
- 在計算型任務中庐氮,使用多進程可以利用計算機的多核優(yōu)勢,能并行執(zhí)行任務宋彼,速度更快弄砍。
計算密集型任務,多進程和和線程的效率比較
from multiprocessing import Process
from threading import Thread
import os,time
def work():
res=0
for i in range(100000000):
res*=i
if __name__ == '__main__':
l=[]
print(os.cpu_count()) #本機為12核
start=time.time()
for i in range(12):
p=Process(target=work) # 使用多進程時間為 9.17792010307312
p=Thread(target=work) # 使用多線程時間為 43.76649355888367
l.append(p)
p.start()
for p in l:
p.join()
stop=time.time()
print('run time is %s' %(stop-start))
# 計算密集型:多進程效率更高
I/O密集型任務输涕,多進程和多線程的效率比較
from multiprocessing import Process
from threading import Thread
import threading
import os,time
def work():
time.sleep(2)
print('===>')
if __name__ == '__main__':
l=[]
print(os.cpu_count()) #本機為4核
start=time.time()
for i in range(400):
p=Process(target=work) # 使用多進程音婶,耗時 6.676343202590942
p=Thread(target=work) # 使用多線程,耗時 2.049600124359131
l.append(p)
p.start()
for p in l:
p.join()
stop=time.time()
print('run time is %s' %(stop-start))
# I/O密集型:多線程效率高
現(xiàn)在計算機基本上都是多核莱坎,python對于計算密集型的任務開多個線程的效率并不能帶來多大的提升衣式,甚至如串行(沒有大量的切換),但是檐什,對于I/O密集型的任務效率還是有顯著提升的碴卧。
- 多線程用于IO密集型,如Socket, 爬蟲厢汹,web
- 多進程用于計算密集型螟深,如金融分析
GIL和python應用程序鎖的關系
GIL鎖并不會保護python程序中的數(shù)據(jù),只在解釋器級別實現(xiàn)鎖的機制烫葬,在python應用中界弧,如果遇到IO操作,已經獲得鎖的線程或者進程或保留鎖的狀態(tài)搭综,其他線程在這種狀態(tài)下獲取鎖進行問的操作垢箕。