Python 多進(jìn)程 (Multiprocessing) 是一種同時(shí)利用計(jì)算機(jī)多個(gè)處理器核心 (CPU cores) 進(jìn)行并行處理的技術(shù),它與 Python 的多線程 (Multithreading) 技術(shù)不同,因?yàn)槎嗑€程的并發(fā)任務(wù)依賴于一個(gè) GIL (Global Interpreter Lock)。在多進(jìn)程中,每個(gè)進(jìn)程都有自己的解釋器進(jìn)程,并且可以同時(shí)使用多個(gè) CPU 核心,因此在處理計(jì)算密集型任務(wù)時(shí)比多線程更有效。
要使用 Python 的多進(jìn)程,我們需要使用內(nèi)置的 multiprocessing 模塊,該模塊提供了創(chuàng)建和管理進(jìn)程的類和函數(shù),下面是一個(gè)簡(jiǎn)單的 Python 多進(jìn)程的例子:
importmultiprocessing defworker(): """子進(jìn)程的工作函數(shù)""" print("Starting worker") # 這里可以放一些耗時(shí)的任務(wù) print("Finished worker") if__name__=='__main__': # 創(chuàng)建一個(gè)子進(jìn)程 p=multiprocessing.Process(target=worker) # 啟動(dòng)子進(jìn)程 p.start() # 等待子進(jìn)程結(jié)束 p.join() print("Parent process finished")
在這個(gè)例子中,我們定義了一個(gè)函數(shù) worker(),這個(gè)函數(shù)是子進(jìn)程要執(zhí)行的任務(wù),我們使用 multiprocessing.Process 類創(chuàng)建了一個(gè)子進(jìn)程,并將 worker() 函數(shù)作為參數(shù)傳遞給 target 參數(shù),然后我們使用 start() 方法啟動(dòng)子進(jìn)程,join() 方法等待子進(jìn)程完成,最后,主進(jìn)程會(huì)輸出一條消息,表示自己已經(jīng)完成了。
除了創(chuàng)建單個(gè)子進(jìn)程,我們還可以使用 Pool 類來(lái)創(chuàng)建多個(gè)子進(jìn)程,以便并行處理多個(gè)任務(wù),下面是一個(gè)使用 Pool 類的例子:
importmultiprocessing defworker(num): """子進(jìn)程的工作函數(shù)""" print(f"Starting worker {num}") # 這里可以放一些耗時(shí)的任務(wù) print(f"Finished worker {num}") if__name__=='__main__': # 創(chuàng)建一個(gè)包含 4 個(gè)進(jìn)程的進(jìn)程池 withmultiprocessing.Pool(processes=4)aspool: # 使用 map 函數(shù)并行執(zhí)行 worker 函數(shù) pool.map(worker, [1,2,3,4]) print("Parent process finished")
在這個(gè)例子中,我們使用 Pool 類創(chuàng)建了一個(gè)包含 4 個(gè)進(jìn)程的進(jìn)程池,然后我們使用 map() 方法并行執(zhí)行 worker() 函數(shù)。map() 方法會(huì)將參數(shù)列表中的每個(gè)參數(shù)依次傳遞給 worker() 函數(shù),并將返回值收集到一個(gè)列表中。最后,主進(jìn)程會(huì)輸出一條消息,表示自己已經(jīng)完成了。
當(dāng)我們需要執(zhí)行一些計(jì)算密集型的任務(wù)時(shí),使用 Python 的多進(jìn)程技術(shù)可以顯著提高程序的執(zhí)行效率,下面是一些使用 Python 的多進(jìn)程技術(shù)的常見場(chǎng)景:
數(shù)據(jù)處理:當(dāng)我們需要處理大量的數(shù)據(jù)時(shí),可以使用多進(jìn)程技術(shù)將數(shù)據(jù)分成多個(gè)部分,并同時(shí)處理它們。
網(wǎng)絡(luò)爬蟲:當(dāng)我們需要爬取大量的網(wǎng)頁(yè)時(shí),可以使用多進(jìn)程技術(shù)將不同的任務(wù)分配給不同的進(jìn)程,從而并行地執(zhí)行它們。
圖像處理:當(dāng)我們需要對(duì)大量的圖像進(jìn)行處理時(shí),可以使用多進(jìn)程技術(shù)并行執(zhí)行不同的處理任務(wù)。
在使用 Python 的多進(jìn)程技術(shù)時(shí),我們需要注意一些問(wèn)題:
進(jìn)程間通信:由于每個(gè)進(jìn)程都有自己的內(nèi)存空間,因此它們之間不能直接共享數(shù)據(jù),我們需要使用 multiprocessing 模塊提供的管道、隊(duì)列等機(jī)制來(lái)實(shí)現(xiàn)進(jìn)程間通信。
進(jìn)程池:在使用 Pool 類時(shí),我們需要注意控制并發(fā)任務(wù)的數(shù)量,以免占用過(guò)多的系統(tǒng)資源。
內(nèi)存限制:由于每個(gè)進(jìn)程都有自己的內(nèi)存空間,因此如果同時(shí)創(chuàng)建太多的進(jìn)程,會(huì)占用過(guò)多的系統(tǒng)內(nèi)存,導(dǎo)致程序崩潰。
下面是一個(gè)使用進(jìn)程池并行執(zhí)行任務(wù)的例子,其中使用了 imap_unordered() 方法來(lái)異步執(zhí)行任務(wù):
importmultiprocessing importtime defsquare(x): """計(jì)算平方""" time.sleep(1) # 模擬耗時(shí)的計(jì)算 returnx*x if__name__=='__main__': # 創(chuàng)建進(jìn)程池 withmultiprocessing.Pool()aspool: # 異步執(zhí)行任務(wù) forresultinpool.imap_unordered(square,range(10)): print(result)
在這個(gè)例子中,我們創(chuàng)建了一個(gè)包含默認(rèn)進(jìn)程數(shù)的進(jìn)程池,然后使用 imap_unordered() 方法并行執(zhí)行 square() 函數(shù)。imap_unordered() 方法會(huì)返回一個(gè)迭代器,每次迭代都會(huì)返回一個(gè)已經(jīng)完成的任務(wù)的結(jié)果。由于我們使用了異步執(zhí)行,因此任務(wù)的返回順序不一定與參數(shù)的順序相同。
除了使用 imap_unordered() 方法,我們還可以使用 imap() 方法,它會(huì)按照參數(shù)的順序返回任務(wù)的結(jié)果,此外,我們還可以使用 apply() 和 apply_async() 方法來(lái)執(zhí)行單個(gè)任務(wù)或異步執(zhí)行單個(gè)任務(wù)。
總的來(lái)說(shuō),使用 Python 的多進(jìn)程技術(shù)可以幫助我們更有效地處理計(jì)算密集型任務(wù),通過(guò)使用 multiprocessing 模塊和 Pool 類,我們可以輕松地創(chuàng)建和管理多個(gè)子進(jìn)程,并使它們并行地執(zhí)行任務(wù)。
審核編輯:湯梓紅
-
處理器
+關(guān)注
關(guān)注
68文章
19259瀏覽量
229649 -
cpu
+關(guān)注
關(guān)注
68文章
10854瀏覽量
211574 -
函數(shù)
+關(guān)注
關(guān)注
3文章
4327瀏覽量
62569 -
python
+關(guān)注
關(guān)注
56文章
4792瀏覽量
84627 -
多進(jìn)程
+關(guān)注
關(guān)注
0文章
14瀏覽量
2615
原文標(biāo)題:Python多進(jìn)程學(xué)習(xí)
文章出處:【微信號(hào):magedu-Linux,微信公眾號(hào):馬哥Linux運(yùn)維】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論