中文字幕日韩精品一区二区免费_精品一区二区三区国产精品无卡在_国精品无码专区一区二区三区_国产αv三级中文在线

Python多進程怎么應(yīng)用

這篇文章主要講解了“Python多進程怎么應(yīng)用”,文中的講解內(nèi)容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“Python多進程怎么應(yīng)用”吧!

創(chuàng)新互聯(lián)2013年開創(chuàng)至今,是專業(yè)互聯(lián)網(wǎng)技術(shù)服務(wù)公司,擁有項目成都做網(wǎng)站、網(wǎng)站建設(shè)、外貿(mào)營銷網(wǎng)站建設(shè)網(wǎng)站策劃,項目實施與項目整合能力。我們以讓每一個夢想脫穎而出為使命,1280元博興做網(wǎng)站,已為上家服務(wù),為博興各地企業(yè)和個人服務(wù),聯(lián)系電話:13518219792

并行和串行計算

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

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

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

Python多進程怎么應(yīng)用

并行編程模型

我們已經(jīng)確定了什么是并行編程,但我們?nèi)绾问褂盟??我們之前說過,并行計算涉及在處理器的多個核心之間執(zhí)行多個任務(wù),這意味著這些任務(wù)是同時執(zhí)行的。在進行并行化之前,你應(yīng)該考慮幾個問題。例如,是否有其他優(yōu)化可以加快我們的計算速度?

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

  • 完全平行。任務(wù)可以獨立運行,不需要相互通信。

  • 共享內(nèi)存并行。進程(或線程)需要通信,因此它們共享一個全局地址空間。

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

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

Python多進程:Python中基于進程的并行性

在 Python 中實現(xiàn)并行性的一種方法是使用multiprocessing模塊。multiprocessing模塊允許你創(chuàng)建多個進程,每個進程都有自己的 Python 解釋器。因此,Python 多進程實現(xiàn)了基于進程的并行。

你可能聽說過其他庫,比如threading,它也是Python內(nèi)置的,但它們之間有著重要的區(qū)別。multiprocessing模塊創(chuàng)建新進程,而threading創(chuàng)建新線程。

使用多進程的好處

你可能會問,“為什么選擇多進程?” 多進程可以通過并行而不是按順序運行多個任務(wù)來顯著提高程序的效率。一個類似的術(shù)語是多線程,但它們是不同的。

進程是加載到內(nèi)存中運行的程序,不與其他進程共享其內(nèi)存。線程是進程中的一個執(zhí)行單元。多個線程在一個進程中運行,并相互共享進程的內(nèi)存空間。

Python的全局解釋器鎖(GIL)只允許在解釋器下一次運行一個線程,這意味著如果需要Python解釋器,你將無法享受多線程的性能優(yōu)勢。這就是在Python中多進程比線程更占優(yōu)勢的原因。多個進程可以并行運行,因為每個進程都有自己的解釋器,執(zhí)行分配給它的指令。此外,操作系統(tǒng)將在多個進程中查看你的程序,并分別對它們進行調(diào)度,即,你的程序在總的計算機資源中占有更大的份額。因此,當程序受到CPU限制時,多進程速度更快。在程序中有大量I/O的情況下,線程可能更高效,因為大多數(shù)時候,程序都在等待I/O完成。然而,多進程通常效率更高,因為它同時運行。

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

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

  • 與線程相比,對子線程的控制更多

  • 易于編碼

第一個優(yōu)點與性能有關(guān)。由于多進程創(chuàng)建了新的進程,你可以通過在其他內(nèi)核之間劃分任務(wù)來更好地利用CPU的計算能力。現(xiàn)在大多數(shù)處理器都是多核處理器,如果你優(yōu)化代碼,可以通過并行計算節(jié)省時間。

第二個優(yōu)點是多線程處理的替代方案。線程不是進程,這有其后果。如果你創(chuàng)建了一個線程,那么像處理正常進程一樣終止它甚至中斷它是很危險的。由于多進程和多線程之間的比較不在本文的范圍內(nèi),后續(xù)我會單獨寫一篇來講講多進程和多線程的區(qū)別。

多進程的第三個優(yōu)點是它很容易實現(xiàn),因為你嘗試處理的任務(wù)適合并行編程。

Python多進程入門

我們終于準備好編寫一些 Python 代碼了!

我們將從一個非?;镜氖纠_始,我們將使用它來說明 Python 多進程的核心方面。在此示例中,我們將有兩個進程:

  • parent經(jīng)常。只有一個父進程,它可以有多個子進程。

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

我們將使用該child過程來執(zhí)行某個函數(shù)。這樣,parent可以繼續(xù)執(zhí)行。

一個簡單的 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)。這個函數(shù)是冒泡排序算法的一個非常簡單的實現(xiàn)。如果你不知道它是什么,請不要擔心,因為它并不重要。要知道的關(guān)鍵是它是一個可以實現(xiàn)某個功能的函數(shù)。

進程類

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

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

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

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

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

在這個例子中,我們只創(chuàng)建了一個子進程。正如你可能猜到的,我們可以通過在Process類中創(chuàng)建更多實例來創(chuàng)建更多子進程。

進程池類

如果我們需要創(chuàng)建多個進程來處理更多 CPU 密集型任務(wù)怎么辦?我們是否總是需要明確地開始并等待終止?這里的解決方案是使用Pool類。

Pool類允許你創(chuàng)建一個工作進程池,在下面的示例中,我們將研究如何使用它。這是我們的新示例:

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)函數(shù),它只接受一個整數(shù)并返回它的平方根。很簡單,對吧?

然后,我們創(chuàng)建一個Pool類的實例,而不指定任何屬性。默認情況下,Pool類為每個 CPU 核心創(chuàng)建一個進程。接下來,我們使用幾個參數(shù)運行map方法。

map方法將cube函數(shù)應(yīng)用于我們提供的可迭代對象的每個元素——在本例中,它是從10N的每個數(shù)字的列表。

這樣做的最大優(yōu)點是列表上的計算是并行進行的!

joblib

joblib是一組使并行計算更容易的工具。它是一個用于多進程的通用第三方庫。它還提供緩存和序列化功能。要安裝joblib包,請在終端中使用以下命令:

pip install joblib

我們可以將之前的示例轉(zhuǎn)換為以下示例以供使用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()函數(shù)是另一個函數(shù)的包裝器,用于生成函數(shù)調(diào)用的“延遲”版本。這意味著它在被調(diào)用時不會立即執(zhí)行函數(shù)。

然后,我們多次調(diào)用delayed函數(shù),并傳遞不同的參數(shù)集。例如,當我們將整數(shù)1賦予cube函數(shù)的延遲版本時,我們不計算結(jié)果,而是分別為函數(shù)對象、位置參數(shù)和關(guān)鍵字參數(shù)生成元組(cube, (1,), {})

我們使用Parallel()創(chuàng)建了引擎實例。當它像一個以元組列表作為參數(shù)的函數(shù)一樣被調(diào)用時,它將實際并行執(zhí)行每個元組指定的作業(yè),并在所有作業(yè)完成后收集結(jié)果作為列表。在這里,我們創(chuàng)建了n_jobs=3Parallel()實例,因此將有三個進程并行運行。

我們也可以直接編寫元組。因此,上面的代碼可以重寫為:

result = Parallel(n_jobs=3)((cube, (i,), {}) for i in range(1,1000))

使用joblib的好處是,我們可以通過簡單地添加一個附加參數(shù)在多線程中運行代碼:

result = Parallel(n_jobs=3, prefer="threads")(delayed(cube)(i) for i in range(1,1000))

這隱藏了并行運行函數(shù)的所有細節(jié)。我們只是使用與普通列表理解沒有太大區(qū)別的語法。

充分利用 Python多進程

創(chuàng)建多個進程并進行并行計算不一定比串行計算更有效。對于 CPU 密集度較低的任務(wù),串行計算比并行計算快。因此,了解何時應(yīng)該使用多進程非常重要——這取決于你正在執(zhí)行的任務(wù)。

為了讓你相信這一點,讓我們看一個簡單的例子:

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個數(shù)的平方根,但有兩種方法。第一個涉及 Python 進程的使用,而第二個不涉及。我們使用time庫中的perf_counter()方法來測量時間性能。

在我的電腦上,我得到了這個結(jié)果:

> python code.py
Program finished in 1.6385094 seconds - using multiprocessing
---
Program finished in 2.7373942999999996 seconds

如你所見,相差不止一秒。所以在這種情況下,多進程更好。

讓我們更改代碼中的某些內(nèi)容,例如N的值。 讓我們把它降低到N=10000,看看會發(fā)生什么。

這就是我現(xiàn)在得到的:

> python code.py
Program finished in 0.3756742 seconds - using multiprocessing
---
Program finished in 0.005098400000000003 seconds

發(fā)生了什么?現(xiàn)在看來,多進程是一個糟糕的選擇。為什么?

與解決的任務(wù)相比,在進程之間拆分計算所帶來的開銷太大了。你可以看到在時間性能方面有多大差異。

感謝各位的閱讀,以上就是“Python多進程怎么應(yīng)用”的內(nèi)容了,經(jīng)過本文的學習后,相信大家對Python多進程怎么應(yīng)用這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是創(chuàng)新互聯(lián),小編將為大家推送更多相關(guān)知識點的文章,歡迎關(guān)注!

當前題目:Python多進程怎么應(yīng)用
網(wǎng)站地址:http://www.rwnh.cn/article14/jgpgde.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站設(shè)計公司、服務(wù)器托管、動態(tài)網(wǎng)站靜態(tài)網(wǎng)站、網(wǎng)站改版、品牌網(wǎng)站制作

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

綿陽服務(wù)器托管
大同市| 永清县| 两当县| 交口县| 应城市| 青河县| 白河县| 平原县| 宝坻区| 朝阳县| 北流市| 璧山县| 海城市| 石门县| 礼泉县| 云梦县| 辉县市| 林口县| 平湖市| 余干县| 奉贤区| 呼玛县| 新津县| 方正县| 韶山市| 神池县| 乌拉特后旗| 兴仁县| 新安县| 大理市| 永川市| 育儿| 南京市| 浏阳市| 宁陵县| 精河县| 镇坪县| 迭部县| 城步| 赞皇县| 鹤山市|