目錄
並行和串行計算
並行程式設計模型
Python多進程:Python中基於進程的平行性
使用多進程的好處
Python多進程入門
一個簡單的Python多進程範例
進程類別
進程池類別
joblib
充分利用 Python多进程
首頁 後端開發 Python教學 Python多進程怎麼應用

Python多進程怎麼應用

May 25, 2023 am 09:28 AM
python

並行和串行計算

想像一下,你有一個巨大的問題要解決,而你獨自一人。你需要計算八個不同數字的平方根。你是做什麼的?你沒有太多選擇。從第一個數字開始,然後計算結果。然後,你繼續和其他人。

如果你有三個擅長數學的朋友願意幫助你呢?他們每個人都會計算兩個數字的平方根,你的工作會更容易,因為工作量在你的朋友之間平均分配。這意味著你的問題將更快解決。

好了,一切都清楚了嗎?在這些例子中,每個朋友代表CPU的核心。在第一個範例中,整個任務由你依序解決。這稱為串行計算。在第二個範例中,由於你總共使用了四個內核,因此你使用的是並行計算。並行計算涉及使用並行進程或在處理器的多個核心之間劃分的進程。

Python多進程怎麼應用

並行程式設計模型

我們已經確定了什麼是並行編程,但我們如何使用它?我們之前說過,平行運算涉及在處理器的多個核心之間執行多個任務,這意味著這些任務是同時執行的。在進行並行化之前,你應該考慮幾個問題。例如,是否有其他最佳化可以加快我們的計算速度?

現在,讓我們理所當然地認為並行化是最適合的解決方案。平行計算主要有三種模式:

  • #完全平行。任務可以獨立運行,不需要相互通訊。

  • 共享記憶體並行。進程(或執行緒)需要通信,因此它們共享一個全域位址空間。

  • 訊息傳遞。進程需要在需要時共享訊息。

在本文中,我們將說明第一個模型,它也是最簡單的。

Python多進程:Python中基於進程的平行性

在 Python 中實現並行性的一種方法是使用multiprocessing 模組。 multiprocessing模組可讓你建立多個進程,每個進程都有自己的 Python 解釋器。因此,Python 多進程實作了基於進程的並行。

你可能聽過其他函式庫,像是threading,它也是Python內建的,但它們之間有著重要的差異。 multiprocessing模組建立新進程,而threading建立新執行緒。

使用多進程的好處

你可能會問,「為什麼選擇多進程?」 多進程可以透過並行而不是按順序運行多個任務來顯著提高程式的效率。一個類似的術語是多線程,但它們是不同的。

進程是載入到記憶體中運行的程序,不與其他進程共享其記憶體。執行緒是進程中的一個執行單元。多個執行緒在一個進程中運行,並相互共享進程的記憶體空間。

Python的全域解釋器鎖定(GIL)只允許在解釋器下一次運行一個線程,這意味著如果需要Python解釋器,你將無法享受多線程的效能優勢。這就是在Python中多進程比執行緒更佔優勢的原因。多個進程可以並行運行,因為每個進程都有自己的解釋器,執行分配給它的指令。此外,作業系統將在多個進程中查看你的程序,並分別對它們進行調度,即,你的程式在總的電腦資源中佔有更大的份額。因此,當程式受到CPU限制時,多進程速度更快。在程式中有大量I/O的情況下,執行緒可能更有高效,因為大多數時候,程式都在等待I/O完成。然而,多進程通常效率更高,因為它同時運行。

以下是多進程的一些好處:

  • 在處理高CPU密集型任務時更好地使用CPU

  • 與執行緒相比,對子執行緒的控制更多

  • 易於編碼

第一個優點與效能有關。由於多進程創建了新的進程,你可以透過在其他核心之間劃分任務來更好地利用CPU的運算能力。現在大多數處理器都是多核心處理器,如果你優化程式碼,可以透過並行計算節省時間。

第二個優點是多執行緒處理的替代方案。執行緒不是進程,這有其後果。如果你創建了一個線程,那麼像處理正常進程一樣終止它甚至中斷它是很危險的。由於多進程和多執行緒之間的比較不在本文的範圍內,後續我會單獨寫一篇來講講多進程和多執行緒的差異。

多進程的第三個優點是它很容易實現,因為你嘗試處理的任務適合併行程式設計。

Python多進程入門

我們終於準備好要寫一些 Python 程式碼了!

我們將從一個非常基本的範例開始,我們將使用它來說明 Python 多進程的核心面向。在這個範例中,我們將有兩個進程:

  • parent經常。只有一個父進程,它可以有多個子進程。

  • child進程。這是由父進程產生的。每個子進程也可以有新的子進程。

我們將使用該child程序來執行某個函數。這樣,parent可以繼續執行。

一個簡單的Python多進程範例

這是我們將用於此範例的程式碼:

from multiprocessing import Process

def bubble_sort(array):
    check = True
    while check == True:
      check = False
      for i in range(0, len(array)-1):
        if array[i] > array[i+1]:
          check = True
          temp = array[i]
          array[i] = array[i+1]
          array[i+1] = temp
    print("Array sorted: ", array)

if __name__ == '__main__':
    p = Process(target=bubble_sort, args=([1,9,4,5,2,6,8,4],))
    p.start()
    p.join()
登入後複製

在這個片段中,我們定義了一個名為bubble_sort(array)。這個函數是冒泡排序演算法的一個非常簡單的實作。如果你不知道它是什麼,請不要擔心,因為它並不重要。要知道的關鍵是它是一個可以實現某個功能的函數。

進程類別

multiprocessing,我們導入類別Process。此類表示將在單獨進程中運行的活動。事實上,你可以看到我們已經傳遞了一些參數:

  • target=bubble_sort,意味著我們的新進程將運行該bubble_sort函數

  • args=([1,9,4,52,6,8,4],),這是作為參數傳遞給目標函數的陣列

一旦我們建立了Process 類別的實例,我們只需要啟動該進程。這是透過編寫p.start()完成的。此時,該進程開始。

在我們退出之前,我們需要等待子程序完成它的計算。此join()方法等待進程終止。

在這個範例中,我們只建立了一個子進程。正如你可能猜到的,我們可以透過在Process類別中建立更多實例來建立更多子進程。

進程池類別

如果我們需要建立多個進程來處理更多 CPU 密集型任務怎麼辦?我們是否總是需要明確地開始並等待終止?這裡的解決方案是使用Pool類別。

Pool類別允許你建立一個工作進程池,在下面的範例中,我們將研究如何使用它。這是我們的新範例:

from multiprocessing import Pool
import time
import math

N = 5000000

def cube(x):
    return math.sqrt(x)

if __name__ == "__main__":
    with Pool() as pool:
      result = pool.map(cube, range(10,N))
    print("Program finished!")
登入後複製

在這個程式碼片段中,我們有一個cube(x)函數,它只接受一個整數並傳回它的平方根。很簡單,對吧?

然後,我們建立一個Pool類別的實例,而不指定任何屬性。預設情況下,Pool類別為每個 CPU 核心建立一個進程。接下來,我們使用幾個參數來執行map方法。

map方法將cube函數應用於我們提供的可迭代物件的每個元素—在本例中,它是從10N的每個數字的清單。

這樣做的最大優點是清單上的計算是並行進行的!

joblib

套件joblib是一組讓平行運算更容易的工具。它是一個用於多進程的通用第三方程式庫。它還提供快取和序列化功能。要安裝joblib套件,請在終端機中使用以下命令:

pip install joblib
登入後複製

我們可以將先前的範例轉換為以下範例以供使用joblib

from joblib import Parallel, delayed
 
def cube(x):
    return x**3
 
start_time = time.perf_counter()
result = Parallel(n_jobs=3)(delayed(cube)(i) for i in range(1,1000))
finish_time = time.perf_counter()
print(f"Program finished in {finish_time-start_time} seconds")
print(result)
登入後複製

事實上,直觀地看到它的作用。 delayed()函數是另一個函數的包裝器,用於產生函數呼叫的「延遲」版本。這意味著它在被呼叫時不會立即執行函數。

然后,我们多次调用delayed函数,并传递不同的参数集。例如,当我们将整数1赋予cube函数的延迟版本时,我们不计算结果,而是分别为函数对象、位置参数和关键字参数生成元组(cube, (1,), {})

我们使用Parallel()创建了引擎实例。当它像一个以元组列表作为参数的函数一样被调用时,它将实际并行执行每个元组指定的作业,并在所有作业完成后收集结果作为列表。在这里,我们创建了n_jobs=3Parallel()实例,因此将有三个进程并行运行。

我们也可以直接编写元组。因此,上面的代码可以重写为:

result = Parallel(n_jobs=3)((cube, (i,), {}) for i in range(1,1000))
登入後複製

使用joblib的好处是,我们可以通过简单地添加一个附加参数在多线程中运行代码:

result = Parallel(n_jobs=3, prefer="threads")(delayed(cube)(i) for i in range(1,1000))
登入後複製

这隐藏了并行运行函数的所有细节。我们只是使用与普通列表理解没有太大区别的语法。

充分利用 Python多进程

创建多个进程并进行并行计算不一定比串行计算更有效。对于 CPU 密集度较低的任务,串行计算比并行计算快。因此,了解何时应该使用多进程非常重要——这取决于你正在执行的任务。

为了让你相信这一点,让我们看一个简单的例子:

from multiprocessing import Pool
import time
import math

N = 5000000

def cube(x):
    return math.sqrt(x)

if __name__ == "__main__":
    # first way, using multiprocessing
    start_time = time.perf_counter()
    with Pool() as pool:
      result = pool.map(cube, range(10,N))
    finish_time = time.perf_counter()
    print("Program finished in {} seconds - using multiprocessing".format(finish_time-start_time))
    print("---")
    # second way, serial computation
    start_time = time.perf_counter()
    result = []
    for x in range(10,N):
      result.append(cube(x))
    finish_time = time.perf_counter()
    print("Program finished in {} seconds".format(finish_time-start_time))
登入後複製

此代码段基于前面的示例。我们正在解决同样的问题,即计算N个数的平方根,但有两种方法。第一个涉及 Python 进程的使用,而第二个不涉及。我们使用time库中的perf_counter()方法来测量时间性能。

在我的电脑上,我得到了这个结果:

> python code.py
Program finished in 1.6385094 seconds - using multiprocessing
---
Program finished in 2.7373942999999996 seconds
登入後複製

如你所见,相差不止一秒。所以在这种情况下,多进程更好。

让我们更改代码中的某些内容,例如N的值。 让我们把它降低到N=10000,看看会发生什么。

这就是我现在得到的:

> python code.py
Program finished in 0.3756742 seconds - using multiprocessing
---
Program finished in 0.005098400000000003 seconds
登入後複製

发生了什么?现在看来,多进程是一个糟糕的选择。为什么?

与解决的任务相比,在进程之间拆分计算所带来的开销太大了。你可以看到在时间性能方面有多大差异。

以上是Python多進程怎麼應用的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

<🎜>:泡泡膠模擬器無窮大 - 如何獲取和使用皇家鑰匙
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
北端:融合系統,解釋
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
Mandragora:巫婆樹的耳語 - 如何解鎖抓鉤
3 週前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

熱門話題

Java教學
1665
14
CakePHP 教程
1423
52
Laravel 教程
1321
25
PHP教程
1269
29
C# 教程
1249
24
PHP和Python:解釋了不同的範例 PHP和Python:解釋了不同的範例 Apr 18, 2025 am 12:26 AM

PHP主要是過程式編程,但也支持面向對象編程(OOP);Python支持多種範式,包括OOP、函數式和過程式編程。 PHP適合web開發,Python適用於多種應用,如數據分析和機器學習。

在PHP和Python之間進行選擇:指南 在PHP和Python之間進行選擇:指南 Apr 18, 2025 am 12:24 AM

PHP適合網頁開發和快速原型開發,Python適用於數據科學和機器學習。 1.PHP用於動態網頁開發,語法簡單,適合快速開發。 2.Python語法簡潔,適用於多領域,庫生態系統強大。

sublime怎麼運行代碼python sublime怎麼運行代碼python Apr 16, 2025 am 08:48 AM

在 Sublime Text 中運行 Python 代碼,需先安裝 Python 插件,再創建 .py 文件並編寫代碼,最後按 Ctrl B 運行代碼,輸出會在控制台中顯示。

PHP和Python:深入了解他們的歷史 PHP和Python:深入了解他們的歷史 Apr 18, 2025 am 12:25 AM

PHP起源於1994年,由RasmusLerdorf開發,最初用於跟踪網站訪問者,逐漸演變為服務器端腳本語言,廣泛應用於網頁開發。 Python由GuidovanRossum於1980年代末開發,1991年首次發布,強調代碼可讀性和簡潔性,適用於科學計算、數據分析等領域。

Python vs. JavaScript:學習曲線和易用性 Python vs. JavaScript:學習曲線和易用性 Apr 16, 2025 am 12:12 AM

Python更適合初學者,學習曲線平緩,語法簡潔;JavaScript適合前端開發,學習曲線較陡,語法靈活。 1.Python語法直觀,適用於數據科學和後端開發。 2.JavaScript靈活,廣泛用於前端和服務器端編程。

Golang vs. Python:性能和可伸縮性 Golang vs. Python:性能和可伸縮性 Apr 19, 2025 am 12:18 AM

Golang在性能和可擴展性方面優於Python。 1)Golang的編譯型特性和高效並發模型使其在高並發場景下表現出色。 2)Python作為解釋型語言,執行速度較慢,但通過工具如Cython可優化性能。

vscode在哪寫代碼 vscode在哪寫代碼 Apr 15, 2025 pm 09:54 PM

在 Visual Studio Code(VSCode)中編寫代碼簡單易行,只需安裝 VSCode、創建項目、選擇語言、創建文件、編寫代碼、保存並運行即可。 VSCode 的優點包括跨平台、免費開源、強大功能、擴展豐富,以及輕量快速。

notepad 怎麼運行python notepad 怎麼運行python Apr 16, 2025 pm 07:33 PM

在 Notepad 中運行 Python 代碼需要安裝 Python 可執行文件和 NppExec 插件。安裝 Python 並為其添加 PATH 後,在 NppExec 插件中配置命令為“python”、參數為“{CURRENT_DIRECTORY}{FILE_NAME}”,即可在 Notepad 中通過快捷鍵“F6”運行 Python 代碼。

See all articles