1. 程式人生 > >day34 GIL鎖 執行緒佇列 執行緒池

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)     #呼叫回撥函式語法