簡體   English   中英

多線程與多處理:select 哪一個?

[英]Multi-Threading vs Multi-Processing : Which one to select?

我已經在這里問了一個關於多處理中的多線程的問題,其結果很難理解,並產生了一個更受歡迎的問題 Multi-threading V/s Multi-Processing。

我已經閱讀了有關此問題的各種帖子,但沒有一個人明確回答 select 而不是另一個,甚至沒有檢查哪一個最適合需要的方法。 從大部分帖子中,我了解到多線程是 I/O,而多處理是 CPU 綁定,但是當我在 CPU 綁定進程的情況下同時使用這兩種方法時,結果不支持可以盲目選擇的假設用於 I/O 的多線程和用於 CPU 限制的多處理。

就我而言,由於該進程受 CPU 限制,因此結果有利於多線程。 我觀察到,有時即使在 CPU 綁定的進程中,多線程與多處理相比也處於領先地位。 我正在尋找可以幫助我選擇其中一種使用的方法?

下面是我的分析,其中我使用 Python 3.7.2 在我的英特爾 i7、第 8 代、8 核、16 GB 機器上運行多進程和多線程代碼(也在 Python 3.8.2 上對其進行了測試)

定義所需的函數和變量
import numpy as np import time import concurrent.futures a = np.arange(100000000).reshape(100, 1000000) def list_double_value(x): y = [] for elem in x: y.append(2 *elem) return y def double_value(x): return 2* x

案例 1(使用 function 列出輸入並將其每個元素乘以 2

使用 list_double_value function 的多進程(耗時 145 秒
 t = time.time() with concurrent.futures.ProcessPoolExecutor() as executor: my_results = executor.map(list_double_value, a) # takes a list and double its value print(time.time()-t)
使用 list_double_value function 的多線程(耗時 28 秒
 t = time.time() with concurrent.futures.ThreadPoolExecutor() as executor: my_results = executor.map(list_double_value, a) print(time.time()-t)

案例 2(使用 function 取一個值並將其乘以 2)

使用雙值進行多處理(耗時 2.73 秒
 t = time.time() with concurrent.futures.ProcessPoolExecutor() as executor: my_results = executor.map(double_value, a) print(time.time()-t)
使用雙值的多線程(耗時 0.2660 秒
 t = time.time() with concurrent.futures.ThreadPoolExecutor() as executor: my_results = executor.map(double_value, a) print(time.time()-t)

從上面的分析來看,每次在為多線程或多處理編寫代碼之前,我們都需要檢查哪些執行得更快並選擇加入,或者是否有任何規則集為 select 提供具體規則超過另一個?

還要讓我知道所有這些結果是否是由於我使用的 lib concurrent.futures 造成的。 (我也不確定lib)

我建議使用 Dask,它可以讓您以針對並行性優化的方式設置計算。 Dask 支持多線程和多處理(以及多台機器),因此您可以編寫一次代碼並嘗試兩種方式。

https://docs.dask.org/en/latest/

Python 的性能和可擴展性受到 Python 引擎內部稱為全局解釋器鎖或 GIL 的機制的極大限制。 這是一個復雜的話題,但簡單地說,GIL 會阻止單個 python 進程充分利用多個 CPU。 因此,當您使用多線程(一個進程中的多個線程)時,您不會看到擁有 2、4 或 8 個 CPU / 內核的性能提升。

多處理是不同的。 在多處理中,使用多個獨立的 Python 進程(每個進程一個線程),每個進程都有自己獨立的 GIL。 每個進程都可以在自己的 CPU 上運行,因此您的程序可以有效地使用更多的系統資源。

如果您需要非常輕量級的任務,則需要線程,因為每個進程都有一些開銷。 某些類型的任務間通信需要線程。 如果您沒有這些需求,通常使用多處理方法會更好。

在多處理中執行多線程將是一種先進的、有點奇怪的方法。 我認為你最好不要混合模式。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM