程序池和執行緒池

2022-07-01 03:45:12 字數 1688 閱讀 2620

系統啟動乙個新執行緒的成本是比較高的,因為它涉及與作業系統的互動。在這種情形下,使用執行緒池可以很好地提公升效能,尤其是當程式中需要建立大量生存期很短暫的執行緒時,更應該考慮使用執行緒池。

執行緒池在系統啟動時即建立大量空閒的執行緒,程式只要將乙個函式提交給執行緒池,執行緒池就會啟動乙個空閒的執行緒來執行它。當該函式執行結束後,該執行緒並不會死亡,而是再次返回到執行緒池中變成空閒狀態,等待執行下乙個函式。

此外,使用執行緒池可以有效地控制系統中併發執行緒的數量。當系統中包含有大量的併發執行緒時,會導致系統效能急劇下降,甚至導致 python 直譯器崩潰,而執行緒池的最大執行緒數引數可以控制系統中併發執行緒的數量不超過此數。可以有效的保護計算機的安全性。

執行緒池的基類是 concurrent.futures 模組中的 executor,executor 提供了兩個子類,即 threadpoolexecutor 和 processpoolexecutor,其中 threadpoolexecutor 用於建立執行緒池,而 processpoolexecutor 用於建立程序池

exectuor 提供了如下常用方法:

程式將 task 函式提交(submit)給執行緒池後,submit 方法會返回乙個 future 物件,future 類主要用於獲取執行緒任務函式的返回值。由於執行緒任務會在新執行緒中以非同步方式執行,因此,執行緒執行的函式相當於乙個「將來完成」的任務,所以 python 使用 future 來代表。

future 提供了如下方法:

from concurrent.futures import threadpoolexecutor,processpoolexecutor

import time

import os

# 示例化池物件

# 不知道引數的情況,預設是當前計算機cpu個數乘以5,也可以指定執行緒個數

pool = processpoolexecutor(5) # 建立了乙個池子,池子裡面有20個執行緒

def task(n):

print(n,os.getpid())

time.sleep(2)

return n**2

def call_back(n):

print('我拿到了結果:%s'%n.result())

"""提交任務的方式

同步:提交任務之後,原地等待任務的返回結果,再繼續執行下一步**

非同步:提交任務之後,不等待任務的返回結果(通過**函式拿到返回結果並處理),直接執行下一步操作

"""# **函式:非同步提交之後一旦任務有返回結果,自動交給另外乙個去執行

if __name__ == '__main__':

# pool.submit(task,1)

t_list =

for i in range(20):

future = pool.submit(task,i).add_done_callback(call_back) # 可通過 future 的 add_done_callback() 方法來新增**函式,該**函式形如 fn(future)。當執行緒任務完成後,程式會自動觸發該**函式,並將對應的 future 物件作為引數傳給該**函式。

# pool.shutdown() # 關閉池子並且等待池子中所有的任務執行完畢

# for p in t_list:

# print('>>>:',p.result())

print('主')

執行緒池和程序池

動態建立程序 或執行緒 是比較耗費時間的,這樣導致較慢的客戶響應。動態建立的子程序 子執行緒 通常只用來為乙個客戶服務,這將導致系統上產生大量的細微程序 或執行緒 程序間的切換將消耗大量的cpu時間。動態建立的子程序是當前程序的完整映像,當前程序必須謹慎地管理其分配的檔案描述符和堆記憶體等系統資源,...

執行緒池和程序池

案例 模擬多個客戶端一同去訪問服務端,讓服務端支援多個客戶端訪問,從而實現併發效果 不考慮粘包問題 import socket from threading import thread server socket.socket def communicate conn 開始通訊 while true...

程序池和執行緒池

from concurrent.futures import threadpoolexecutor,processpoolexecutor import time,random,os def task name,n print s s is running name,os.getpid time.s...