首頁 >後端開發 >Python教學 >Python多處理和並行編程指南

Python多處理和並行編程指南

Lisa Kudrow
Lisa Kudrow原創
2025-02-19 08:26:11457瀏覽

Python多處理和並行編程指南

加速計算是每個人都想實現的目標。如果您的腳本可以比目前的運行時間快十倍,該怎麼辦?在本文中,我們將研究Python多處理和一個名為多處理的庫。我們將討論什麼是多處理,其優勢以及如何通過使用並行編程來改善Python程序的運行時間。

好吧,讓我們走吧!

>

鑰匙要點

並行計算是一種通過同時使用CPU的多個內核來加速計算的方法。這可以通過多處理在Python中實現,該模塊允許創建多個進程,每個過程都在單獨的核心上運行。
    。 Python的多處理模塊提供了諸如高度密集型任務的CPU使用更好的好處,與線程相比,對兒童流程的更多控制以及適合併行編程的任務的實施方便。 Python多處理並不總是比串行計算更有效。對於低CPU密集型任務,由於流程之間的計算引入的開銷,串行計算的速度可以更快。 Python中的多處理模塊為每個任務創建一個新的過程,需要同時執行。每個過程都有自己的Python解釋器和內存空間,可以獨立於其他過程運行。
  • 在Python中進行多處理可以大大提高程序的速度和效率,但它也會提高代碼的複雜性。並非所有任務都適合併行化,在某些情況下,創建和管理多個流程的開銷大於潛在的性能增長。
  • 平行概論
  • >在我們深入研究Python代碼之前,我們必須談論並行計算,這是計算機科學中的一個重要概念。
  • >通常,當您運行Python腳本時,您的代碼在某個時候變成一個過程,並且該過程在CPU的單個核心上運行。但是現代計算機有多個核心,那麼,如果您可以使用更多的核心進行計算怎麼辦?事實證明,您的計算會更快。
  • >
  • >現在將其作為一般原則,但是後來,在本文中,我們將看到這不是普遍的真實。
  • >
>沒有介紹太多細節,並行性背後的想法是以一種可以使用CPU多個內核的方式編寫代碼。

使事情變得更容易,讓我們來看一個示例。

>

>平行和串行計算

想像您有一個巨大的問題要解決,您一個人。您需要計算八個不同數字的平方根。你做什麼工作?好吧,您沒有很多選擇。您從第一個數字開始,然後計算結果。然後,您繼續與其他人一起。

>如果您有三個擅長幫助您的數學擅長的朋友怎麼辦?他們每個人都會計算兩個數字的平方根,並且您的工作將更容易,因為工作負載平均分佈在您的朋友之間。這意味著您的問題將被更快地解決。

>

好吧,這一切都很清楚嗎?在這些示例中,每個朋友代表CPU的核心。在第一個示例中,整個任務由您順序解決。這稱為串行計算。在第二個示例中,由於您總共使用四個內核,因此您正在使用並行計算。並行計算涉及處理器中多個內核之間的並行過程或過程的使用。

>

Python多處理和並行編程指南

並行編程的

模型

我們已經建立了什麼是平行編程,但是我們如何使用它?好吧,我們在該並行計算之前說過,涉及處理器多個內核之間的多個任務,這意味著這些任務是同時執行的。在接近並行化之前,您應該考慮一些問題。例如,還有其他優化可以加快我們的計算嗎?

>目前,讓我們理所當然地認為並行化是您的最佳解決方案。並行計算中主要有三個模型:

    完全平行。這些任務可以獨立運行,並且不需要彼此交流。
  • >
  • >共享記憶並行性。流程(或線程)需要進行交流,因此它們共享一個全球地址空間。 >
  • 消息傳遞。流程需要在需要時共享消息。
  • 在本文中,我們將說明第一個模型,這也是最簡單的。
> Python多處理:Python中的基於過程的並行性 在Python中實現並行性的一種方法是使用多處理模塊。多處理模塊使您可以創建多個過程,每個過程都使用其自己的Python解釋器。因此,python多處理實現了基於過程的並行性。

>

>您可能聽說過其他庫,例如螺紋,這些庫也與Python一起內置,但是它們之間存在著重要的差異。多處理模塊會創建新的過程,而線程創建新線程。

在下一部分中,我們將研究使用多處理的優勢。

>

使用多處理

的好處

以下是多處理的一些好處:

    在处理高CPU密集型任务时,CPU更好地使用了CPU 与线程相比,对儿童的控制更多
  • 易于编码
  • 第一个优势与性能有关。由于多处理创建了新的过程,因此您可以通过将任务划分为其他内核来更好地利用CPU的计算能力。如今,大多数处理器是多核处理器,如果您优化代码,可以通过并行解决计算来节省时间。
  • 第二个优势着眼于多线程的多处理替代方案。线程不是过程,这会带来后果。如果您创建线程,那么杀死它或甚至像正常过程一样中断它是危险的。由于本文的多处理和多线程之间的比较不在本文的范围内,因此我鼓励您对其进行一些进一步的阅读。
>

多处理的第三个优点是,鉴于您要处理的任务非常适合并行编程。

开始使用Python多处理

我们终于准备好编写一些Python代码!

>

我们将从一个非常基本的示例开始,我们将使用它来说明Python多处理的核心方面。在此示例中,我们将有两个进程:

>

父程进程。只有一个父程流程可以有多个孩子。

儿童过程。这是由父母产生的。每个孩子也可以有新孩子。

    >我们将使用子进程执行某个功能。通过这种方式,父母可以继续执行。
  • >
  • 一个简单的python多处理示例
  • 这是我们将用于此示例的代码:

在此片段中,我们定义了一个称为Bubble_Sort(数组)的函数。此功能是气泡排序算法的真正幼稚实现。如果您不知道它是什么,请不要担心,因为这并不重要。要知道的至关重要的是,这是一个有效的函数。

>

过程类

>从多处理中,我们导入类过程。该类代表将在单独的过程中运行的活动。确实,您可以看到我们已经通过了一些论点:

<span>from multiprocessing import Process
</span>
<span>def bubble_sort(array):
</span>    check <span>= True
</span>    <span>while check == True:
</span>      check <span>= False
</span>      <span>for i in range(0, len(array)-1):
</span>        <span>if array[i] > array[i+1]:
</span>          check <span>= True
</span>          temp <span>= array[i]
</span>          array<span>[i] = array[i+1]
</span>          array<span>[i+1] = temp
</span>    <span>print("Array sorted: ", array)
</span>
<span>if __name__ == '__main__':
</span>    p <span>= Process(target=bubble_sort, args=([1,9,4,5,2,6,8,4],))
</span>    p<span>.start()
</span>    p<span>.join()
</span>

> target = bubble_sort,这意味着我们的新过程将运行Bubble_sort函数

args =([[1,9,4,52,6,8,4],),这是作为参数传递给目标函数

的数组

>我们为流程类创建了一个实例,我们只需要启动该过程即可。这是通过编写p.start()来完成的。在这一点上,该过程已开始。
  • >在退出之前,我们需要等待子过程完成其计算。 JOIN()方法等待该过程终止。
  • >

    在此示例中,我們僅創建了一個子進程。您可能猜到,我們可以通過在過程類中創建更多實例來創建更多的子過程。

    池類

    如果我們需要創建多個流程來處理更多CPU密集型任務,該怎麼辦?我們是否總是需要明確等待終止?這裡的解決方案是使用池類類。

    >池類允許您創建一個工作過程池,在下面的示例中,我們將研究如何使用它。這是我們的新示例:

<span>from multiprocessing import Process
</span>
<span>def bubble_sort(array):
</span>    check <span>= True
</span>    <span>while check == True:
</span>      check <span>= False
</span>      <span>for i in range(0, len(array)-1):
</span>        <span>if array[i] > array[i+1]:
</span>          check <span>= True
</span>          temp <span>= array[i]
</span>          array<span>[i] = array[i+1]
</span>          array<span>[i+1] = temp
</span>    <span>print("Array sorted: ", array)
</span>
<span>if __name__ == '__main__':
</span>    p <span>= Process(target=bubble_sort, args=([1,9,4,5,2,6,8,4],))
</span>    p<span>.start()
</span>    p<span>.join()
</span>
>在此代碼段中,我們有一個立方體(x)函數,該函數僅採用整數並返回其平方根。容易,對嗎?

然後,我們創建一個池類的實例,而無需指定任何屬性。池類類別默認每個CPU核心創建一個進程。接下來,我們使用一些參數運行地圖方法。

地圖方法將立方體函數應用於我們提供的峰值的每個元素 - 在這種情況下,這是從10到N的每個數字的列表。

的巨大優勢是,列表上的計算是並行完成的!

>

>充分利用Python多處理

創建多個過程和進行並行計算不一定比串行計算更有效。對於低CPU密集型任務,串行計算比並行計算快。因此,重要的是要了解何時應該使用多處理 - 這取決於您執行的任務。

為了說服您,讓我們看一個簡單的例子:>

此片段基於上一個示例。我們正在解決相同的問題,該問題正在計算n個數字的平方根,但有兩種方式。第一個涉及Python多處理的使用,而第二個則沒有使用。我們正在使用時間庫中的perf_counter()方法來衡量時間性能。

在我的筆記本電腦上,我得到了這個結果:

如您所見,有一個以上的差異。因此,在這種情況下,多處理更好。
<span>from multiprocessing import Pool
</span><span>import time
</span><span>import math
</span>
N <span>= 5000000
</span>
<span>def cube(x):
</span>    <span>return math.sqrt(x)
</span>
<span>if __name__ == "__main__":
</span>    <span>with Pool() as pool:
</span>      result <span>= pool.map(cube, range(10,N))
</span>    <span>print("Program finished!")
</span>

>讓我們在代碼中更改某些內容,例如N的值。讓我們將其降低到n = 10000,看看會發生什麼。

>

這就是我現在得到的:

<span>from multiprocessing import Pool
</span><span>import time
</span><span>import math
</span>
N <span>= 5000000
</span>
<span>def cube(x):
</span>    <span>return math.sqrt(x)
</span>
<span>if __name__ == "__main__":
</span>    <span># first way, using multiprocessing
</span>    start_time <span>= time.perf_counter()
</span>    <span>with Pool() as pool:
</span>      result <span>= pool.map(cube, range(10,N))
</span>    finish_time <span>= time.perf_counter()
</span>    <span>print("Program finished in {} seconds - using multiprocessing".format(finish_time-start_time))
</span>    <span>print("---")
</span>    <span># second way, serial computation
</span>    start_time <span>= time.perf_counter()
</span>    result <span>= []
</span>    <span>for x in range(10,N):
</span>      result<span>.append(cube(x))
</span>    finish_time <span>= time.perf_counter()
</span>    <span>print("Program finished in {} seconds".format(finish_time-start_time))
</span>

發生了什麼事?現在,多處理現在是一個不好的選擇。為什麼?

與解決的任務相比,通過在過程之間分配計算來引入的高架太多。您可以看到時間表現有多大的區別。

>

結論

在本文中,我們通過使用Python多處理來討論了Python代碼的性能優化。

首先,我們簡要介紹了哪些並行計算是使用它的主要模型。然後,我們開始談論多處理及其優勢。最後,我們看到平行化計算並不總是最佳選擇,並且應將多處理模塊用於並行化CPU結合任務。與往常一樣,考慮到您要面臨的具體問題並評估不同解決方案的利弊是一個問題。

我希望您發現學習有關Python的多處理與我一樣有用。

關於Python多處理和並行編程

的常見問題

>在Python中使用多處理的主要優點是什麼?在處理CPU密集型任務時,這是特別有益的,因為它使該程序能夠利用CPU的多個內核,從而顯著提高了程序的速度和效率。與螺紋不同,多處理不會遭受Python中全局解釋器鎖(GIL)的困擾,這意味著每個過程都可以獨立運行而不會受到其他過程的影響。這使得多處理在Python中進行並行編程的功能。

>

>如何使用Python中的多處理模塊工作?同時執行。每個過程都有自己的Python解釋器和內存空間,這意味著它可以獨立於其他過程運行。多處理模塊提供了許多類和功能,使創建和管理這些過程變得容易。例如,該過程類用於創建一個新的過程,而池類類用於管理一個工作過程。 > Python中多處理和多線程之間的主要區別在於它們如何處理任務。在多處理為每個任務創建一個新過程時,多線程在同一過程中創建一個新線程。這意味著,雖然多處理可以充分利用多個CPU內核,但多線程受到Python中的全局解釋器鎖(GIL)的限制,該python中只允許一次執行一個線程。但是,多線程仍然對I/O結合任務很有用,該程序花費大部分時間等待輸入/輸出操作完成。

>如何使用多處理模塊的共享內存機制來實現Python中的過程之間的數據?這些包括值和數組類,這些類別允許分別創建共享變量和數組。但是,重要的是要注意,由於每個過程都有自己的內存空間,因此對共享變量進行的更改或一個過程中的數組的更改將不會反映在其他過程中,除非它們使用鎖或其他由多處理模塊提供的同步基原始人明確同步。在python中使用多處理的潛在陷阱是什麼? Python可以大大提高您計劃的速度和效率,它也帶來了自己的挑戰。主要陷阱之一是代碼的複雜性增加。管理多個過程比管理單線程程序更複雜,尤其是在處理共享數據和同步過程時。此外,創建一個新過程比創建新線程更含有資源密集型,這可能會導致內存使用增加。最後,並非所有任務都適合併行化,在某些情況下,創建和管理多個流程的開銷大於潛在的性能增長。

>我如何處理Python多處理的例外? python中多處理中的異常可能有些棘手,因為在子進程中發生的例外不會自動傳播到父過程。但是,多處理模塊提供了幾種處理異常的方法。一種方法是使用過程類的is_alive()方法檢查進程是否仍在運行。如果該方法返回false,則意味著該過程已終止,這可能是由於例外。另一種方法是使用該過程類的出口碼屬性,它可以提供有關為什麼終止過程的更多信息。

我可以與其他python庫多處理?其他Python庫。但是,重要的是要注意,並非所有庫都設計用於在多處理環境中。某些庫可能不是線程安全的,也可能不支持並發執行。因此,檢查您使用的庫文檔總是一個好主意,以查看它是否支持多處理。

>

>我如何在Python中調試多處理程序?

>調試Python中的多處理程序可能會具有挑戰性,因為傳統調試工具可能在多處理環境中無法正常工作。但是,您可以使用幾種技術來調試程序。一種方法是使用打印語句或記錄來跟踪程序的執行。另一種方法是使用PDB模塊的set_trace()函數在代碼中設置斷點。您還可以使用支持多處理的專業調試工具,例如多處理模塊的log_to_stderr()函數,它允許您將進程的活動記錄到標準錯誤。作業系統?

是的,您可以在不同操作系統上使用Python中使用多處理。多處理模塊是標準Python庫的一部分,這意味著它可以在支持Python的所有平台上可用。但是,由於它們處理過程的差異,多處理模塊的行為可能在不同的操作系統之間略有不同。因此,最好在目標操作系統上測試您的程序以確保其按預期運行。在Python中使用多處理包括:

- 避免在可能的情況下在過程之間共享數據,因為這可能會導致複雜的同步問題。

- 使用池類管理您的工作人員流程,因為它提供了一個更高級別的界面,該界面簡化了創建和管理流程的過程。

- 始終通過調用流程類的join()方法來清理過程,該方法可確保該過程在程序繼續之前完成。

- 正確處理異常,以防止您的程序出乎意料的崩潰。

- 徹底測試您的程序以確保其在多處理環境中正確工作。

>

以上是Python多處理和並行編程指南的詳細內容。更多資訊請關注PHP中文網其他相關文章!

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