国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 編程 > Python > 正文

python實(shí)現(xiàn)多進(jìn)程代碼示例

2020-01-04 14:10:44
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

想要充分利用多核CPU資源,Python中大部分情況下都需要使用多進(jìn)程,Python中提供了multiprocessing這個(gè)包實(shí)現(xiàn)多進(jìn)程。multiprocessing支持子進(jìn)程、進(jìn)程間的同步與通信,提供了Process、Queue、Pipe、Lock等組件。

開(kāi)辟子進(jìn)程

multiprocessing中提供了Process類來(lái)生成進(jìn)程實(shí)例

Process([group [, target [, name [, args [, kwargs]]]]])

  • group分組,實(shí)際上不使用
  • target表示調(diào)用對(duì)象,你可以傳入方法的名字
  • args表示給調(diào)用對(duì)象以元組的形式提供參數(shù),比如target是函數(shù)a,他有兩個(gè)參數(shù)m,n,那么該參數(shù)為args=(m, n)即可
  • kwargs表示調(diào)用對(duì)象的字典
  • name是別名,相當(dāng)于給這個(gè)進(jìn)程取一個(gè)名字

先來(lái)個(gè)小例子:

# -*- coding:utf-8 -*-from multiprocessing import Process, Poolimport osimport timedef run_proc(wTime):  n = 0  while n < 3:    print "subProcess %s run," % os.getpid(), "{0}".format(time.ctime())  #獲取當(dāng)前進(jìn)程號(hào)和正在運(yùn)行是的時(shí)間    time.sleep(wTime)  #等待(休眠)    n += 1if __name__ == "__main__":  p = Process(target=run_proc, args=(2,)) #申請(qǐng)子進(jìn)程  p.start()   #運(yùn)行進(jìn)程  print "Parent process run. subProcess is ", p.pid  print "Parent process end,{0}".format(time.ctime())

運(yùn)行結(jié)果:

Parent process run. subProcess is 30196 
Parent process end,Mon Mar 27 11:20:21 2017 
subProcess 30196 run, Mon Mar 27 11:20:21 2017 
subProcess 30196 run, Mon Mar 27 11:20:23 2017 
subProcess 30196 run, Mon Mar 27 11:20:25 2017

根據(jù)運(yùn)行結(jié)果可知,父進(jìn)程運(yùn)行結(jié)束后子進(jìn)程仍然還在運(yùn)行,這可能造成僵尸( zombie)進(jìn)程。

通常情況下,當(dāng)子進(jìn)程終結(jié)時(shí),它會(huì)通知父進(jìn)程,清空自己所占據(jù)的內(nèi)存,并在內(nèi)核里留下自己的退出信息。父進(jìn)程在得知子進(jìn)程終結(jié)時(shí),會(huì)從內(nèi)核中取出子進(jìn)程的退出信息。但是,如果父進(jìn)程早于子進(jìn)程終結(jié),這可能造成子進(jìn)程的退出信息滯留在內(nèi)核中,子進(jìn)程成為僵尸(zombie)進(jìn)程。當(dāng)大量僵尸進(jìn)程積累時(shí),內(nèi)存空間會(huì)被擠占。

有什么辦法可以避免僵尸進(jìn)程呢? 

這里介紹進(jìn)程的一個(gè)屬性 deamon,當(dāng)其值為T(mén)RUE時(shí),其父進(jìn)程結(jié)束,該進(jìn)程也直接終止運(yùn)行(即使還沒(méi)運(yùn)行完)。 
所以給上面的程序加上p.deamon = true,看看效果。

# -*- coding:utf-8 -*-from multiprocessing import Process, Poolimport osimport timedef run_proc(wTime):  n = 0  while n < 3:    print "subProcess %s run," % os.getpid(), "{0}".format(time.ctime())    time.sleep(wTime)    n += 1if __name__ == "__main__":  p = Process(target=run_proc, args=(2,))  p.daemon = True  #加入daemon  p.start()  print "Parent process run. subProcess is ", p.pid  print "Parent process end,{0}".format(time.ctime())

執(zhí)行結(jié)果:

Parent process run. subProcess is 31856 
Parent process end,Mon Mar 27 11:40:10 2017

這是問(wèn)題又來(lái)了,子進(jìn)程并沒(méi)有執(zhí)行完,這不是所期望的結(jié)果。有沒(méi)辦法將子進(jìn)程執(zhí)行完后才讓父進(jìn)程結(jié)束呢? 

這里引入p.join()方法,它使子進(jìn)程執(zhí)行結(jié)束后,父進(jìn)程才執(zhí)行之后的代碼

# -*- coding:utf-8 -*-from multiprocessing import Process, Poolimport osimport timedef run_proc(wTime):  n = 0  while n < 3:    print "subProcess %s run," % os.getpid(), "{0}".format(time.ctime())    time.sleep(wTime)    n += 1if __name__ == "__main__":  p = Process(target=run_proc, args=(2,))  p.daemon = True  p.start()  p.join()  #加入join方法  print "Parent process run. subProcess is ", p.pid  print "Parent process end,{0}".format(time.ctime())

執(zhí)行結(jié)果:

subProcess 32076 run, Mon Mar 27 11:46:07 2017 
subProcess 32076 run, Mon Mar 27 11:46:09 2017 
subProcess 32076 run, Mon Mar 27 11:46:11 2017 
Parent process run. subProcess is 32076 
Parent process end,Mon Mar 27 11:46:13 2017

這樣所有的進(jìn)程就能順利的執(zhí)行了。

將進(jìn)程定義成類

通過(guò)繼承Process類,來(lái)自定義進(jìn)程類,實(shí)現(xiàn)run方法。實(shí)例p通過(guò)調(diào)用p.start()時(shí)自動(dòng)調(diào)用run方法。 

如下:

# -*- coding:utf-8 -*-from multiprocessing import Process, Poolimport osimport timeclass Myprocess(Process):  def __init__(self, wTime):    Process.__init__(self)    self.wTime = wTime  def run(self):    n = 0    while n < 3:      print "subProcess %s run," % os.getpid(), "{0}".format(time.ctime())      time.sleep(self.wTime)      n += 1if __name__ == "__main__":  p = Myprocess(2)  p.daemon = True  p.start()  #自動(dòng)調(diào)用run方法  p.join()  print "Parent process run. subProcess is ", p.pid  print "Parent process end,{0}".format(time.ctime())

執(zhí)行結(jié)果和上一個(gè)例子相同。

創(chuàng)建多個(gè)進(jìn)程

很多時(shí)候系統(tǒng)都需要?jiǎng)?chuàng)建多個(gè)進(jìn)程以提高CPU的利用率,當(dāng)數(shù)量較少時(shí),可以手動(dòng)生成一個(gè)個(gè)Process實(shí)例。當(dāng)進(jìn)程數(shù)量很多時(shí),或許可以利用循環(huán),但是這需要程序員手動(dòng)管理系統(tǒng)中并發(fā)進(jìn)程的數(shù)量,有時(shí)會(huì)很麻煩。這時(shí)進(jìn)程池Pool就可以發(fā)揮其功效了。可以通過(guò)傳遞參數(shù)限制并發(fā)進(jìn)程的數(shù)量,默認(rèn)值為CPU的核數(shù)。 

直接上例子:

# -*- coding:utf-8 -*-from multiprocessing import Process,Poolimport os,timedef run_proc(name):    ##定義一個(gè)函數(shù)用于進(jìn)程調(diào)用  for i in range(5):      time.sleep(0.2)  #休眠0.2秒    print 'Run child process %s (%s)' % (name, os.getpid())#執(zhí)行一次該函數(shù)共需1秒的時(shí)間if __name__ =='__main__': #執(zhí)行主進(jìn)程  print 'Run the main process (%s).' % (os.getpid())  mainStart = time.time() #記錄主進(jìn)程開(kāi)始的時(shí)間  p = Pool(8)      #開(kāi)辟進(jìn)程池  for i in range(16):                 #開(kāi)辟14個(gè)進(jìn)程    p.apply_async(run_proc,args=('Process'+str(i),))#每個(gè)進(jìn)程都調(diào)用run_proc函數(shù),                            #args表示給該函數(shù)傳遞的參數(shù)。  print 'Waiting for all subprocesses done ...'  p.close() #關(guān)閉進(jìn)程池  p.join() #等待開(kāi)辟的所有進(jìn)程執(zhí)行完后,主進(jìn)程才繼續(xù)往下執(zhí)行  print 'All subprocesses done'  mainEnd = time.time() #記錄主進(jìn)程結(jié)束時(shí)間  print 'All process ran %0.2f seconds.' % (mainEnd-mainStart) #主進(jìn)程執(zhí)行時(shí)間

執(zhí)行結(jié)果: 

開(kāi)頭部分

Run the main process (30920). 
Waiting for all subprocesses done … 
Run child process Process0 (32396) 
Run child process Process3 (25392) 
Run child process Process1 (28732) 
Run child process Process2 (32436)

末尾部分:

Run child process Process15 (25880) 
All subprocesses done 
All process last 2.49 seconds.

相關(guān)說(shuō)明:

這里進(jìn)程池對(duì)并發(fā)進(jìn)程的限制數(shù)量為8個(gè),而程序運(yùn)行時(shí)會(huì)產(chǎn)生16個(gè)進(jìn)程,進(jìn)程池將自動(dòng)管理系統(tǒng)內(nèi)進(jìn)程的并發(fā)數(shù)量,其余進(jìn)程將會(huì)在隊(duì)列中等待。限制并發(fā)數(shù)量是因?yàn)椋到y(tǒng)中并發(fā)的進(jìn)程不是越多越好,并發(fā)進(jìn)程太多,可能使CPU大部分的時(shí)間用于進(jìn)程調(diào)度,而不是執(zhí)行有效的計(jì)算。

采用多進(jìn)程并發(fā)技術(shù)時(shí),就單個(gè)處理機(jī)而言,其對(duì)進(jìn)程的執(zhí)行是串行的。但具體某個(gè)時(shí)刻哪個(gè)進(jìn)程獲得CPU資源而執(zhí)行是不可預(yù)知的(如執(zhí)行結(jié)果的開(kāi)頭部分,各進(jìn)程的執(zhí)行順序不定),這就體現(xiàn)了進(jìn)程的異步性。

如果單個(gè)程序執(zhí)行14次run_proc函數(shù),那么它會(huì)需要至少16秒,通過(guò)進(jìn)程的并發(fā),這里只需要2.49秒,可見(jiàn)并發(fā)的優(yōu)勢(shì)。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持VEVB武林網(wǎng)。


注:相關(guān)教程知識(shí)閱讀請(qǐng)移步到python教程頻道。
發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 安宁市| 山东| 新绛县| 永春县| 宜宾市| 东城区| 晋宁县| 涪陵区| 金沙县| 田阳县| 玉山县| 满洲里市| 沁阳市| 汉中市| 龙陵县| 苍梧县| 绥德县| 多伦县| 叶城县| 江门市| 双牌县| 醴陵市| 青川县| 永平县| 甘德县| 军事| 华亭县| 云南省| 屏东县| 肃北| 新安县| 秦安县| 昌图县| 揭西县| 武川县| 古丈县| 承德市| 巴林右旗| 电白县| 怀仁县| 石台县|