從python3.2開始,標準庫為我們提供了concurrent.futures模組,它提供了threadpoolexecutor和processpoolexecutor兩個類,實現了對threading和multiprocessing的進一步
抽象(這裡主要關注執行緒池),不僅可幫我們自動排程執行緒,還可以做到:
1、主線程可以獲取某乙個執行緒(或者任務的)的狀態,以及返回值。
2、當乙個執行緒完成的時候,主線程能夠立即知道。
3、讓多執行緒和多程序的編碼介面一致。
獲取任務是否完成,取消任務和獲取任務的返回結果
from concurrent.futures importthreadpoolexecutor
import
time
#引數times用來模擬網路請求的時間
defget_html(times, name):
time.sleep(times)
print(f"
get page finished")
return
times
tp = threadpoolexecutor(max_workers=2)
#通過submit函式提交執行的函式到執行緒池中,submit函式立即返回,不阻塞
task1 = tp.submit(get_html, *(3, "
執行緒1"
))task2 = tp.submit(get_html, *(2, "
執行緒2"))#
done方法用於判定某個任務是否完成
print("
done?
", task1.done())
#cancel方法用於取消某個任務,該任務沒有放入執行緒池中才能取消成功
print("
cancel?
", task2.cancel())
time.sleep(4)
print("
done?
", task1.done())
#result方法可以獲取task的執行結果
print("
result?
", task1.result())
執行結果:
done? falsecancel? false
執行緒2 get page 2finished
執行緒1 get page 3finished
done? true
result? 3
1、threadpoolexecutor構造例項的時候,傳入max_workers引數來設定執行緒池中最多能同時執行的執行緒數目。
2、使用submit函式來提交執行緒需要執行的任務(函式名和引數)到執行緒池中,並返回該任務的控制代碼(類似於檔案、畫圖),注意submit()不是阻塞的,而是立即返回。
3、通過submit函式返回的任務控制代碼,能夠使用done()方法判斷該任務是否結束。上面的例子可以看出,由於任務有2s的延時,在task1提交後立刻判斷,task1還未完成,
而在延時4s之後判斷,task1就完成了。
改變執行緒池的大小為1,那麼先提交的是task1,task2還在排隊等候,這個時候可以成功取消。
5、使用result()方法可以獲取任務的返回值。檢視內部**,發現這個方法是阻塞的。
as_completed方法一次取出所有任務的結果
from concurrent.futures importthreadpoolexecutor, as_completed
import
time
#引數times用來模擬網路請求的時間
defget_html(times):
time.sleep(times)
print(f"
get page finished")
return
times
tp = threadpoolexecutor(max_workers=2)
lst = [3, 2, 4]
all_task = [tp.submit(get_html, (i)) for i in
lst]
for future in
as_completed(all_task):
data =future.result()
print(f"
in main: get page success
")
執行結果:
get page 2finishedin main: get page 2success
get page 3finished
in main: get page 3success
get page 4finished
in main: get page 4 success
map
from concurrent.futures importthreadpoolexecutor
import
time
#引數times用來模擬網路請求的時間
defget_html(times):
time.sleep(times)
print(f"
get page finished")
return
times
tp = threadpoolexecutor(max_workers=2)
lst = [3, 2, 4]
for i in
tp.map(get_html, lst):
print(f"
in main: get page success
")
執行結果:
get page 2finishedget page 3finished
in main: get page 3success
in main: get page 2success
get page 4finished
in main: get page 4 success
wait方法可以讓主線程阻塞,知道滿足設定的要求
from concurrent.futures importthreadpoolexecutor
import
time
#引數times用來模擬網路請求的時間
defget_html(times):
time.sleep(times)
print(f"
get page finished")
return
times
tp = threadpoolexecutor(max_workers=2)
lst = [3, 2, 4]
for i in
tp.map(get_html, lst):
print(f"
in main: get page success
")
執行結果:
get page 2finishedget page 3finished
in main: get page 3success
in main: get page 2success
get page 4finished
in main: get page 4 success
ThreadPoolExecutor執行緒池原始碼解讀
主要變數 private volatile int corepoolsize private volatile int maximumpoolsize private volatile int poolsize 建構函式 也就是建立類的時候,需要注入引數。public threadpoolexecu...
ThreadPoolExecutor執行緒池引數設定
jdk1.5中引入了強大的concurrent包,其中最常用的莫過了執行緒池的實現threadpoolexecutor,它給我們帶來了極大的方便,但同時,對於該執行緒池不恰當的設定也可能使其效率並不能達到預期的效果,甚至僅相當於或低於單執行緒的效率。threadpoolexecutor類可設定的引數...
ThreadPoolExecutor執行緒池
python中已經有了threading模組,為什麼還需要執行緒池呢,執行緒池又是什麼東西呢?在介紹執行緒同步的訊號量機制的時候,舉得例子是爬蟲的例子,需要控制同時爬取的執行緒數,例子中建立了20個執行緒,而同時只允許3個執行緒在執行,但是20個執行緒都需要建立和銷毀,執行緒的建立是需要消耗系統資源...