Python多進(jìn)程運(yùn)行——Multiprocessing基礎(chǔ)教程1

多進(jìn)程是什么

多進(jìn)程指的是操作系統(tǒng)同時(shí)支持多個(gè)處理器的能力岛蚤。在支持多任務(wù)操作系統(tǒng)中,一個(gè)應(yīng)用程序會被分解成多個(gè)獨(dú)立運(yùn)行的較小的程序恐仑。操作系統(tǒng)會將這些線程分配到多核處理器择同,以提升系統(tǒng)性能。

為什么需要多進(jìn)程

假設(shè)我們的計(jì)算機(jī)只有一個(gè)單核的處理器轨奄,然后同時(shí)被分配了幾個(gè)任務(wù)孟害,那么它就不得不在各個(gè)任務(wù)中來回切換,短暫地執(zhí)行其中一個(gè)任務(wù)戚绕,然后中斷纹坐,然后短暫地執(zhí)行下一個(gè)任務(wù),以保持所有的進(jìn)程都在運(yùn)行。這就像一個(gè)廚師在做面條耘子,切幾秒鐘菜果漾,跑去揉幾下面,再趕緊查看下湯谷誓。

所以同時(shí)需要完成的任務(wù)越多绒障,同時(shí)跟蹤所有的任務(wù)就越困難。這就是多進(jìn)程的必要性捍歪,也是多核處理器的威力所在户辱。

一個(gè)支持多進(jìn)程的操作系統(tǒng)可以做到:

  • 同時(shí)指揮多個(gè)CPU,即擁有一個(gè)以上的CPU的計(jì)算機(jī)
  • 指揮多核CPU糙臼,即擁有兩個(gè)及以上的獨(dú)立處理單元的CPU

這樣庐镐,計(jì)算機(jī)就可以輕松地同時(shí)執(zhí)行多個(gè)任務(wù),每個(gè)任務(wù)都可以使用自己的處理器变逃。就像之前舉的例子必逆,現(xiàn)在廚房里有專門的揉面師傅,備菜師傅揽乱,煮湯師傅名眉。事情就變得輕松多了。

用Python執(zhí)行多進(jìn)程

學(xué)習(xí)Python的優(yōu)勢之一就是它擁有海量的第三方模塊凰棉。今天我們再來介紹一個(gè)能幫你輕松完成多進(jìn)程并行的模塊:

multiprocessing

multiprocessing模塊支持使用類似于threading模塊的API生成進(jìn)程损拢。multiprocessing模塊提供了本地和遠(yuǎn)程計(jì)算機(jī)的并行處理能力,并且通過使用創(chuàng)建子進(jìn)程撒犀,有效地避開了全局解釋器鎖(GIL)福压。因此,multiprocessing模塊允許程序員充分利用機(jī)器上的多個(gè)處理器绘证。目前隧膏,它可以在Unix和Windows上運(yùn)行。

multiprocessing的模塊的API非常簡單直觀嚷那,可以讓新手迅速上手在多個(gè)進(jìn)程之間劃分工作胞枕。我們現(xiàn)在看一個(gè)簡單的例子:

# importing the multiprocessing module 
import multiprocessing 
  
def print_cube(num): 
    print("Cube: {}".format(num * num * num)) 
    
def print_square(num): 
    print("Square: {}".format(num * num)) 
    
if __name__ == "__main__": 
    # creating processes 
    p1 = multiprocessing.Process(target=print_square, args=(10, )) 
    p2 = multiprocessing.Process(target=print_cube, args=(10, )) 
    
    # starting process 1&2
    p1.start() 
    p2.start() 
    
    # wait until process 1&2 is finished 
    p1.join() 
    p2.join() 
    
    # both processes finished 
    print("Done!") 

運(yùn)行結(jié)果是這樣的:

Square: 100
Cube: 1000
Done!

其實(shí)代碼的含義非常簡單了,首先我們導(dǎo)入了multiprocessing模塊魏宽,隨后定義了兩個(gè)函數(shù)腐泻,它們的功能分別是打印一個(gè)數(shù)的三次方和打印一個(gè)數(shù)的平方。

之后關(guān)鍵的步驟來了队询,要?jiǎng)?chuàng)建多個(gè)進(jìn)程派桩,首先需要?jiǎng)?chuàng)建Process類的對象。在這個(gè)例子中Process類接收了兩個(gè)參數(shù):

  • target:在進(jìn)程中被執(zhí)行的函數(shù)
  • args:向被執(zhí)行函數(shù)傳遞的參數(shù)

當(dāng)然蚌斩,進(jìn)程構(gòu)造函數(shù)還可以接受許多其他參數(shù)铆惑,我們之后會更詳細(xì)地介紹。在上面的例子中,我們創(chuàng)建了兩個(gè)具有不同目標(biāo)函數(shù)的進(jìn)程:

p1 = multiprocessing.Process(target=print_square, args=(10, ))
p2 = multiprocessing.Process(target=print_cube, args=(10, )) 

隨后的start()方法就是開始執(zhí)行p1员魏,p2兩個(gè)進(jìn)程丑蛤。在進(jìn)程開始執(zhí)行后,主程序仍然會繼續(xù)執(zhí)行撕阎。為了讓主程序暫停受裹,我們就使用了join()方法。它的作用就是將主程序暫停虏束,直到等待p1和p2完成棉饶。一旦它們都完成了,再執(zhí)行之后的語句镇匀。

讓我們再舉一個(gè)例子照藻,來理解同一個(gè)腳本中運(yùn)行不同進(jìn)程的概念。在下面的例子中汗侵,我們打印運(yùn)行目標(biāo)函數(shù)的進(jìn)程ID:

# importing the multiprocessing module 
import multiprocessing 
import os 
  
def worker1(): 
    # printing process id 
    print("ID of process running worker1: {}".format(os.getpid())) 
def worker2(): 
    # printing process id 
    print("ID of process running worker2: {}".format(os.getpid())) 
    
if __name__ == "__main__": 
    # printing main program process id 
    print("ID of main process: {}".format(os.getpid())) 
    
    # creating processes 
    p1 = multiprocessing.Process(target=worker1) 
    p2 = multiprocessing.Process(target=worker2) 
    
    # starting processes 
    p1.start() 
    p2.start() 
    
    # process IDs 
    print("ID of process p1: {}".format(p1.pid)) 
    print("ID of process p2: {}".format(p2.pid)) 
    
    # wait until processes are finished 
    p1.join() 
    p2.join() 
    
    # both processes finished 
    print("Both processes finished execution!") 
    
    # check if processes are alive 
    print("Process p1 is alive: {}".format(p1.is_alive())) 
    print("Process p2 is alive: {}".format(p2.is_alive())) 

上面這個(gè)程序的輸出結(jié)果如下:

ID of main process: 28628
ID of process running worker1: 29305
ID of process running worker2: 29306
ID of process p1: 29305
ID of process p2: 29306
Both processes finished execution!
Process p1 is alive: False
Process p2 is alive: False

主python腳本有一個(gè)獨(dú)立的進(jìn)程ID岩梳,當(dāng)我們創(chuàng)建進(jìn)程對象p1和p2時(shí),multiprocessing模塊會生成具有不同進(jìn)程ID的新進(jìn)程晃择。os.getpid()函數(shù)是用來獲取運(yùn)行當(dāng)前目標(biāo)函數(shù)的進(jìn)程的ID。上述輸出結(jié)果也可以看到也物,使用os.getpid()獲取的進(jìn)程ID與通過進(jìn)程類的pid屬性獲得的ID是一致的宫屠。

上面的每個(gè)進(jìn)程都是獨(dú)立運(yùn)行的,并且擁有自己獨(dú)立的內(nèi)存空間滑蚯。

一旦目標(biāo)函數(shù)執(zhí)行完成浪蹂,進(jìn)程就會終止。在上面的程序中告材,我們使用了Process類的is_alive()方法來檢查進(jìn)程是否仍然處于活動狀態(tài)坤次。

最后用下面的圖來幫助理解記憶新進(jìn)程與主Python腳本的不同之處:

圖1 進(jìn)程ID示意圖.png

這篇文章是對Python中的多進(jìn)程的一個(gè)初步介紹。接下來的幾篇文章將進(jìn)一步介紹多進(jìn)程相關(guān)知識斥赋。

敬請期待吧缰猴!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市疤剑,隨后出現(xiàn)的幾起案子滑绒,更是在濱河造成了極大的恐慌,老刑警劉巖隘膘,帶你破解...
    沈念sama閱讀 221,635評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件疑故,死亡現(xiàn)場離奇詭異,居然都是意外死亡弯菊,警方通過查閱死者的電腦和手機(jī)纵势,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,543評論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人钦铁,你說我怎么就攤上這事软舌。” “怎么了育瓜?”我有些...
    開封第一講書人閱讀 168,083評論 0 360
  • 文/不壞的土叔 我叫張陵葫隙,是天一觀的道長。 經(jīng)常有香客問我躏仇,道長恋脚,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,640評論 1 296
  • 正文 為了忘掉前任焰手,我火速辦了婚禮糟描,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘书妻。我一直安慰自己船响,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,640評論 6 397
  • 文/花漫 我一把揭開白布躲履。 她就那樣靜靜地躺著见间,像睡著了一般。 火紅的嫁衣襯著肌膚如雪工猜。 梳的紋絲不亂的頭發(fā)上米诉,一...
    開封第一講書人閱讀 52,262評論 1 308
  • 那天,我揣著相機(jī)與錄音篷帅,去河邊找鬼史侣。 笑死,一個(gè)胖子當(dāng)著我的面吹牛魏身,可吹牛的內(nèi)容都是我干的惊橱。 我是一名探鬼主播,決...
    沈念sama閱讀 40,833評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼箭昵,長吁一口氣:“原來是場噩夢啊……” “哼税朴!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起宙枷,我...
    開封第一講書人閱讀 39,736評論 0 276
  • 序言:老撾萬榮一對情侶失蹤掉房,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后慰丛,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體卓囚,經(jīng)...
    沈念sama閱讀 46,280評論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,369評論 3 340
  • 正文 我和宋清朗相戀三年诅病,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了哪亿。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片粥烁。...
    茶點(diǎn)故事閱讀 40,503評論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖蝇棉,靈堂內(nèi)的尸體忽然破棺而出讨阻,到底是詐尸還是另有隱情,我是刑警寧澤篡殷,帶...
    沈念sama閱讀 36,185評論 5 350
  • 正文 年R本政府宣布钝吮,位于F島的核電站,受9級特大地震影響板辽,放射性物質(zhì)發(fā)生泄漏奇瘦。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,870評論 3 333
  • 文/蒙蒙 一劲弦、第九天 我趴在偏房一處隱蔽的房頂上張望耳标。 院中可真熱鬧,春花似錦邑跪、人聲如沸次坡。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,340評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽砸琅。三九已至,卻和暖如春轴踱,著一層夾襖步出監(jiān)牢的瞬間明棍,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,460評論 1 272
  • 我被黑心中介騙來泰國打工寇僧, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人沸版。 一個(gè)月前我還...
    沈念sama閱讀 48,909評論 3 376
  • 正文 我出身青樓嘁傀,卻偏偏與公主長得像,于是被迫代替她去往敵國和親视粮。 傳聞我的和親對象是個(gè)殘疾皇子细办,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,512評論 2 359