執行緒池 程序池

2022-01-20 16:38:29 字數 4270 閱讀 4737

執行緒池&程序池

池子解決什麼問題?

1.建立/銷毀執行緒伴隨著系統開銷,如果過於頻繁會影響系統執行效率

2.執行緒併發數量過多,搶占系統資源,從而導致系統阻塞甚至宕機

3.能夠剛好的控制和管理池子裡面的執行緒和程序

concurrent.futures模組提供了高度封裝的非同步呼叫介面

threadpoolexecutor:執行緒池,提供非同步呼叫

processpoolexecutor:程序池,提供非同步呼叫

常用方法

submit(fn, *args, **kwargs):非同步提交任務

map(func, *iterables, timeout=none, chunksize=1):取代for迴圈submit的操作

shutdown(wait=true):相當於程序池的pool.close()+pool.join()操作

​ wait=true,等待池內所有任務執行完畢**完資源後才繼續

​ wait=false,立即返回,並不會等待池內的任務執行完畢

​ 但不管wait引數為何值,整個程式都會等到所有任務執行完畢

​ submit和map必須在shutdown之前

result(timeout=none):取得結果

add_done_callback(fn):**函式

done():判斷某乙個執行緒是否完成

cancle():取消某個任務

例1 基本用法

from concurrent.futures import threadpoolexecutor,processpoolexecutor

import os,time,random

def work(i):

print(f"work-搬了一塊磚頭")

time.sleep(1)

return "zx"

if __name__ == '__main__':

executor=processpoolexecutor(max_workers=3)

#工人們

futures=

for i in range(11):

future=executor.submit(work,i)

#執行緒池shutdown 關閉入口,等待所有任務結束

executor.shutdown(true)

#列印執行的結果

for future in futures:

print(future.result())

work-0搬了一塊磚頭

work-1搬了一塊磚頭

work-2搬了一塊磚頭

work-3搬了一塊磚頭

work-4搬了一塊磚頭

work-5搬了一塊磚頭

work-6搬了一塊磚頭

work-7搬了一塊磚頭

work-8搬了一塊磚頭

work-9搬了一塊磚頭

work-10搬了一塊磚頭

zxzx

zxzx

zxzx

zxzx

zxzx

zx

注意這樣用會是不對的

from concurrent.futures import threadpoolexecutor,processpoolexecutor

import os,time,random

def work(i):

print(f"work-搬了一塊磚頭")

time.sleep(1)

return "zx"

if __name__ == '__main__':

executor=processpoolexecutor(max_workers=3)

for i in range(11):

future=executor.submit(work,i)

print(future.result())

work-0搬了一塊磚頭

zxwork-1搬了一塊磚頭

zxwork-2搬了一塊磚頭

zxwork-3搬了一塊磚頭

zxwork-4搬了一塊磚頭

zxwork-5搬了一塊磚頭

zxwork-6搬了一塊磚頭

zxwork-7搬了一塊磚頭

zxwork-8搬了一塊磚頭

zxwork-9搬了一塊磚頭

zxwork-10搬了一塊磚頭

zx

例2 基礎執行緒池加**用法

from concurrent.futures import threadpoolexecutor,processpoolexecutor

import threading

import time,random

def work(i):

#獲取當前執行緒物件

thread = threading.current_thread()

print(f"搬了第塊磚頭")

time.sleep(random.randint(1,3))

return i

def call_back(zx):

res = zx.result()

print(res)

if __name__ == '__main__':

#執行緒池為可裝執行緒3個

executor=threadpoolexecutor(max_workers=3)

for i in range(11):

executor.submit(work,i).add_done_callback(call_back)

threadpoolexecutor-0_0搬了第0塊磚頭

threadpoolexecutor-0_1搬了第1塊磚頭

threadpoolexecutor-0_2搬了第2塊磚頭

0threadpoolexecutor-0_0搬了第3塊磚頭

2threadpoolexecutor-0_2搬了第4塊磚頭

1threadpoolexecutor-0_1搬了第5塊磚頭

3threadpoolexecutor-0_0搬了第6塊磚頭

5threadpoolexecutor-0_1搬了第7塊磚頭

4threadpoolexecutor-0_2搬了第8塊磚頭

6threadpoolexecutor-0_0搬了第9塊磚頭

9threadpoolexecutor-0_0搬了第10塊磚頭78

10

例3 程序池加**函式

from concurrent.futures import threadpoolexecutor,processpoolexecutor

import time,random,os

def work(i):

#列印當前程序pid

print(f"搬了第塊磚頭")

time.sleep(random.randint(1,3))

return i

def call_back(zx):

res = zx.result()

print(res)

if __name__ == '__main__':

#執行緒池為可裝執行緒3個

executor=processpoolexecutor(max_workers=3)

for i in range(11):

executor.submit(work,i).add_done_callback(call_back)

18696搬了第0塊磚頭

22500搬了第1塊磚頭

4172搬了第2塊磚頭

22500搬了第3塊磚頭

122500搬了第4塊磚頭

318696搬了第5塊磚頭

04172搬了第6塊磚頭

222500搬了第7塊磚頭

418696搬了第8塊磚頭

518696搬了第9塊磚頭

84172搬了第10塊磚頭67

910

程序池 執行緒池

程序池和執行緒池相似,所以這裡我們以程序池為例介紹,下面對程序池的討論完全適用於執行緒池 如果沒有特殊宣告 程序池是由伺服器預先建立的一組子程序,這些子程序的數目在3 10個之間 典型情況 執行緒池的數量應該和cpu數量差不多。程序池中的所有子程序都執行者相同的 並具有相同的屬性。因為程序池在伺服器...

程序池, 執行緒池

知識儲備 池 裝載固定數量介質,該介質值得是程序或者執行緒 為什麼要用?讓機器在自己可承受的範圍內去保證乙個高效的工作 from concurrent.futures import processpoolexecutor,threadpoolexecutor pool processpoolexec...

程序池 執行緒池

在保證計算機硬體安全的情況下最大限度的利用計算機 池其實是降低了程式的執行效率,但是保證了計算機硬體的安全 硬體的發展跟不上軟體的速度 from concurrent.futures import processpoolexecutor p processpoolexecutor 5 def tas...