day34 GIL鎖 執行緒佇列 執行緒池
一、Gil鎖(Global Interpreter Lock)
python全域性直譯器鎖,有了這個鎖的存在,python直譯器在同一時間內只能讓一個程序中的一個執行緒去執行,這樣python的多執行緒就無法利用多核優勢,但是這並不是python語言本身的缺點,是直譯器的缺點,這個問題只存在於Cpython解釋其中,像Jpython就沒有。但是Cpthon是python官方直譯器(算目前執行效率最高的吧),所以多數人都以為Gil鎖是python語言的弊端。
#GIL鎖圖解
過程解釋:
1、載入python直譯器程式碼
2、載入自己的py檔案
3、py檔案作為引數傳給直譯器(因為有GIL鎖,一次只能一個執行緒進入)
4、直譯器將py檔案編譯成.pyc位元組碼檔案
5、直譯器通過虛擬機器將位元組碼檔案轉為二進位制檔案
6、二進位制檔案等待cpu呼叫
二、執行緒佇列
import queue
執行緒佇列有三種形式
1、先進先出
q = queue.Queue(3) 建立一個長度為3的佇列,先進先出
q.put()
q.get()
q.size() #當前佇列中有多少個元素
2、後進先出
q = queue.LifoQueue(3) 建立一個長度為3的後進先出佇列
3、優先順序佇列
q = queue.PriorityQueue(3) 建立一個長度為3的優先順序佇列
1 import queue 2 # q = queue.Queue() 3 # q =queue.LifoQueue() 4 q = queue.PriorityQueue() #優先順序佇列 5 # put裡是一個元組,元組的一個元素代表優先順序(通常是數字,也可以是非數字,數字越小,優先順序越高),第二個元素是存入佇列中的值 6 #一個佇列中,優先順序必須是同一種資料型別,才能比較,否則會報錯 7 #優先順序佇列詳解如果優先順序相同,那麼按照後面值的ASCII碼的順序來排序 8 #優先順序相同的資料,他們後面的值必須是相同的資料型別才能比較,但優先順序相同的兩個字典無法比較 9 10 # q.put((-1,'ca')) #優先順序相同的兩個字串,逐個比較ASCII碼值 11 # q.put((-1,'cb')) 12 13 # q.put(("a","d")) #優先順序為非數值型別 14 # q.put(('b',"c")) 15 16 # q.put((1,{1:'hh',2:'ss'})) #優先順序相同的兩個字典,無法比較,報錯 17 # q.put((1,{3:'dd',4:'jj'})) 18 19 q.put((2,(4,5))) #優先順序相同的元組,逐個比較元組元素值 20 q.put((2,(4,4))) 21 22 print(q.get()) 23 print(q.get())
三、concurrent.futures模組
通過這個模組可以建立和使用執行緒池和程序池
格式
from concurrent.futures import ThreadPoolExecutor, ProcessPoolExecutor
t = ThreadPoolExecutor(max_workers=4) #建立一個執行緒池物件,容量為4
方法:
t.submit(fun,*args,*kwargs) #非同步提交任務
res= t.submit(fun,*args,*kwargs) #返回值是一個物件
res.result() #從物件中取值,會等待任務的執行結果,等不到是阻塞
t.shutdown) #等待已提交任務完成,相當於close()和join()的效果
t.map(fun, iter) #非同步提交任務
res = t.map(fun, iter) #返回結果是一個生成器物件
for el in res: #取值
print(el)
add_done_callback(fun2) #添加回調函式
t.submit(fun1,引數).add_don_callback(fun2) #呼叫回撥函式語法