1. 程式人生 > 其它 >multiprocessing — Process-based parallelism python 多程序 用法 程序池

multiprocessing — Process-based parallelism python 多程序 用法 程序池

技術標籤:python語言

https://docs.python.org/3/library/multiprocessing.html

1 背景

python由於Global Interpreter Lock 的原因,多執行緒並不是我們想的那種CPU排程的多執行緒,在python中開了多執行緒其實也是一個單程序。
針對CPU密集型(CPU-bound)的任務,比如計算氣象資料,多執行緒和多程序呼叫多個CPU核心並行,能有效減少任務計算時間,提高實時性,但python的多執行緒是不ok的。
針對IO密集型(I/O bound)的任務,比如爬蟲,多執行緒和多程序也是OK的,python的多執行緒顯然也是ok的。

程序會佔用更多資源,比如主程序開一個子程序,子程序會把主程序的變數啥的複製一份,這也導致程序之間通訊和執行緒不一樣。多執行緒的時候,給一個全域性列表進去還能執行緒安全;多程序的時候,子程序只會把主程序的全域性列表複製一份帶入,修改的也是修改子程序的。所以需要類似訊號、管道、訊息佇列、共享記憶體的東西來進行,python multiprocessing有訊息佇列、管道、共享記憶體,優點是快,缺點是不太靈活(儲存型別和執行機制),python multiprocessing提供了一個更高階的封裝類Manager來專門處理這個事情,Manager自己就是一個服務程序,有點就是靈活,缺點就是慢一些。

2 程序池

程序池肯定是很爽的,使用簡單,效果顯著。

windows需要multiprocessing.freeze_support()
Linux不需要。



import multiprocessing
import time
import os


def func1(inputdata, res):
    res.append([sum(inputdata)])
    print("res此時的結果: ", res)
    print("此時的時間: ", time.time())
    print("進城的PID: "
, os.getpid()) if __name__ == '__main__': multiprocessing.freeze_support() res = multiprocessing.Manager().list() # 通訊 inputdata = [i for i in range(100)] # 隨便弄點數 p = multiprocessing.Pool(2) # 建立一個包含2個程序的程序池 p.apply_async(func=func1, args=(inputdata[0:10], res,)) # 往池子里加一個非同步執行的子進城 p.apply_async(func=func1, args=(inputdata[10:20], res,)) # 往池子里加一個非同步執行的子程序 p.apply_async(func=func1, args=(inputdata[20:30], res,)) # 往池子里加一個非同步執行的子程序 p.close() # 等子程序執行完畢後關閉程序池 p.join() # 主程序等待

執行結果:

res此時的結果:  [[45]]
此時的時間:  1610254954.318595
進城的PID:  15372
res此時的結果:  [[45], [245]]
此時的時間:  1610254954.3205965
進城的PID:  15372
res此時的結果:  [[45], [245], [145]]
此時的時間:  1610254954.321597
進城的PID:  16268