什么是MultiProcessing?
- MultiProcessing允許在程式中生成多個行程,
- 它允許在計算機上利用多個 CPU內核
- 程式中的多個行程不共享記憶體
- 全域解釋器鎖定限制:只允許一個執行緒控制 Python 解釋器
- 用于計算或 CPU 密集型程式
那么什么是多執行緒, 什么時候使用它?
執行緒
- 在程式中執行的最小獨立命令集
- 應用程式中的多個執行緒可以在稱為多執行緒的 CPU上同時執行
- 始終在程式內運行,不能自己運行
- 當程式受網路系結或存在繁重的 I/O 操作時使用
- 記憶體在行程中的多個執行緒之間共享,因此資源消耗較低

下面演示MultiProcessing不共享記憶體的代碼,而Multi-Threading共享記憶體的代碼,
在下面的代碼中,我們檢查串列中傳遞的數字是否為底數,我們將使用Multi-Threading多執行緒以及MultiProcessing多處理來做到這一點
使用多執行緒共享全域變數
我們創建了一個全域串列變數,prime_list存盤所有質數,
通過所有數字list_of_num并檢查數字是否為質數,
import threading
import time
prime_list=[]
def get_prime_numbers(numbers):
for num in numbers:
time.sleep(1)
if check_if_prime(num)==True:
prime_list.append(num)
return prime_list
def check_if_prime(num):
if num > 1:
# check for factors
for i in range(2,num):
if (num % i) == 0:
return False
break
else:
return True
# if input number is less than or equal to 1,then not a prime
else:
return False
def main():
start_time=time.perf_counter()
list_of_num=[9,13,12312, 121, 1913, 97, 57, 34, 37, 89, 81 , 87, 23, 27]
t1 = threading.Thread(target=get_prime_numbers, args=[list_of_num])
t1.start()
t1.join()
end_time=time.perf_counter()
print(f"Total time of Thread execution {round(end_time- start_time,4)} for the function ")
print(f'Prime numbers {prime_list} from {list_of_num}')
if __name__=='__main__':
main()
當執行緒共享記憶體或全域變數時,這些值將持久化,我們可以在程式的輸出中看到這一點,

使用Multiprocessing共享全域變數
它的功能與上述功能相同,但我們使用了Multiprocessing庫而不是執行緒,
對于Multiprocessing,創建 Process實體,然后將要執行的函式傳遞給目標,將所有引數傳遞給 args,這與多執行緒相同,
使用行程 process.start() 啟動行程,
主行程等待子行程使用join()完成,
import multiprocessing
import time
prime_list=[]
def get_prime_numbers(numbers):
for num in numbers:
time.sleep(1)
if check_if_prime(num)==True:
prime_list.append(num)
return prime_list
def check_if_prime(num):
if num > 1:
# check for factors
for i in range(2,num):
if (num % i) == 0:
return False
break
else:
return True
# if input number is less than or equal to 1 else not prime
else:
return False
def main():
start_time=time.perf_counter()
list_of_num=[9,13,12312, 121, 1913, 97, 57, 34, 37, 89, 81 , 87, 23, 27]
print("No. of CPU's ", multiprocessing.cpu_count())
p1 = multiprocessing.Process(target=get_prime_numbers, args=[list_of_num])
p1.start()
p1.join()
end_time=time.perf_counter()
print(f"Total time of Thread execution {round(end_time- start_time,4)} for the function ")
print(f'Prime numbers {prime_list} from {list_of_num}')
if __name__=='__main__':
main()
由于每個行程都有其全域變數的副本,因此我們看到全域變數(prime_list)為空

您也可以轉到任務管理器,并在詳細資訊選項卡下查看多個 python .exe運行

ProcessPoolExecutor
ProcessPoolExector 是一種簡單的方法來實作和生成多個行程,使用concurrent.futures.

concurrent.futures有一個抽象類執行器,它有兩個具體的子類
ThreadPoolExecutor:用于多執行緒
ProcessPoolExecutor:用于多處理
在下面,我們使用ProcessPoolExecutor讀取 CSV 檔案,然后列印檔案中的記錄數,
import concurrent.futures
import time
import pandas as pd
def read_data(file):
t1= time.perf_counter()
data= pd.read_csv(file)
#data = data.sort_index(ascending=False)
time.sleep(1)
t2= time.perf_counter()
print(f"Took {round(t2-t1,4)} (sec) time to read data in {file}" )
return f' No. of Records in file {file} are {len(data)}'
def main():
start_time=time.perf_counter()
with concurrent.futures.ThreadPoolExecutor() as executor:
file_list=['pollution.csv', 'good_inpu.csv', 'iris.csv']
return_results=[executor.submit(read_data, file) for file in file_list]
for f in concurrent.futures.as_completed(return_results):
print(f.result())
end_time=time.perf_counter()
print(f"Total time of execution {round(end_time- start_time,4)} for the function")
if __name__=='__main__':
main()

結論
對于 I/O 或網路密集型程式,請使用Threading 類或 ThreadPoolExecutor進行多執行緒處理,
對于 Python 中的計算或 CPU 密集型程式并避免 GIL 限制,請使用multiprocessing 或 ProcessPoolExecutor,
CSDN認證博客專家
機器學習
深度學習
神經網路
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/246556.html
標籤:python
上一篇:Java之分支結構
