當前位置:成語大全網 - 書法字典 - python如何實現壹個過程

python如何實現壹個過程

為了充分利用多核CPU資源,Python在大多數情況下需要使用多進程,Python中提供了包多處理來實現多進程。多處理支持子進程和進程之間的同步和通信,並提供進程、隊列、管道和鎖等組件。

打開壹個子流程

Process類是在多重處理中提供的,用於生成流程實例。

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

分組分組,實際上並沒有用到。

Target表示調用對象,可以傳入方法名。

Args的意思是以元組的形式給調用對象提供參數。例如,target是函數A,它有兩個參數m,n,所以參數是args=(m,n)。

Kwargs表示調用對象的字典。

Name是別名,相當於給這個進程起了壹個名字。

先說壹個小例子:

# -*-編碼:utf-8-*-來自多處理導入進程,pool import OS import time def run _ proc(wTime):

n = 0

而n & lt3: print "子進程% s run," % os.getpid()," {0} "format (time.ctime ()) #獲取當前進程號和運行時間。

Time.sleep(wTime) # Wait (sleep)

n+= 1 if _ _ name _ _ = = " _ _ main _ _ ":

p = Process(target=run_proc,args=(2,)?#申請子流程

運行流程

打印“父流程運行”。子進程是“p.pid print”父進程end,{0}。format(time . ctime())1234567891011213141516171819

運行結果:

父流程運行。子流程是30196?

父流程結束,Mon Mar 27 11:20:21 2017?

子流程30196運行,Mon Mar 27 11:20:21 2017?

子流程30196運行,Mon Mar 27 11:20:23 2017?

子流程30196運行,周壹至3月27日11:20:25 2017

從運行結果來看,父進程運行後子進程還在運行,可能會造成僵屍進程。

通常,當子進程終止時,它會通知父進程,清除它所占用的內存,並在內核中留下自己的退出信息。當父進程知道子進程結束時,它會從內核中取出子進程的退出信息。但是,如果父進程在子進程之前終止,這可能會導致子進程的退出信息留在內核中,子進程就會變成僵屍進程。當僵屍進程大量積累時,內存空間就會被擠壓。

有什麽辦法可以避免僵屍進程??

本文介紹了進程的壹個屬性deamon。當其值為TRUE時,其父進程結束,該進程也直接終止運行(即使尚未結束運行)。?

所以在上面的程序中加上p.deamon = true,看看效果。

# -*-編碼:utf-8-*-來自多處理導入進程,pool import OS import time def run _ proc(wTime):

n = 0

而n & lt3: print "子進程%s run," % os.getpid()," {0} "格式(time.ctime())

睡眠時間(wTime)

n+= 1 if _ _ name _ _ = = " _ _ main _ _ ":

p =進程(target=run_proc,args=(2,))

P.daemon = True #加入守護進程

p.start() print "父進程運行。子進程是“p.pid print”父進程end,{0}。format(time . ctime())123456789101121314151617181920

實施結果:

父流程運行。子流程是31856?

父流程結束,周壹至三月27日11:40:10 2017

又是這個問題,子流程沒有完成,這不是預期的結果。子進程執行後,有沒有辦法結束父進程??

這裏引入P.join()方法,使得父進程只有在子進程執行完畢後才執行下面的代碼。

# -*-編碼:utf-8-*-來自多處理導入進程,pool import OS import time def run _ proc(wTime):

n = 0

而n & lt3: print "子進程%s run," % os.getpid()," {0} "格式(time.ctime())

睡眠時間(wTime)

n+= 1 if _ _ name _ _ = = " _ _ main _ _ ":

p =進程(target=run_proc,args=(2,))

p.daemon = True

開始()

P.join() #添加聯接方法

打印“父流程運行”。子進程是“p.pid print”父進程end,{0}。format(time . ctime())12345678910112131415161718192021

實施結果:

子流程32076運行,Mon Mar 27 11:46:07 2017?

子流程32076運行,3月27日星期壹11:46:09 2017?

子流程32076運行,3月27日星期壹11:46:11 2017?

父流程運行。子流程是32076?

父流程結束,周壹至三月27日11:46:13 2017

這樣所有的過程都可以順利進行。

將流程定義為類

通過繼承process類,可以自定義Process類,實現run方法。實例p通過調用p.start()自動調用run方法。?

如下所示:

# -*-編碼:utf-8-*-來自多處理導入進程,pool import OS import time class my Process(Process):

def __init__(self,wTime):

過程。__init__(self)

self.wTime = wTime def run(self):

n = 0

而n & lt3: print "子進程%s run," % os.getpid()," {0} "格式(time.ctime())

time.sleep(self.wTime)

n+= 1 if _ _ name _ _ = = " _ _ main _ _ ":

p = Myprocess(2)

p.daemon = True

P.start() #自動調用run方法。

p.join() print "父進程運行。子進程是“p.pid print”父進程end,{0}。format(time . ctime())1234567891011213141516171819202122232428

執行結果與前面的示例相同。

創建多個流程

在很多情況下,系統需要創建多個進程來提高CPU的利用率。當數量較少時,可以手工生成壹個流程實例。當進程數量較大時,可能會使用循環,但這需要程序員手動管理系統中並發進程的數量,有時非常麻煩。這時候進程池池就可以發揮作用了。您可以通過傳遞參數來限制並發進程的數量。默認值是CPU核心的數量。?

直接上例:

#-*-編碼:utf-8-*-from多處理導入進程,pool導入OS,timedef run _ proc (name): # #為進程調用定義壹個函數。

對於範圍(5)中的I:

Time.sleep(0.2) #睡眠0.2秒。

Print' run子進程% s(% s)%(name,os.getpid ()) #如果_ _ name _ =' _ _ main _': #執行主進程,則執行此函數壹次需要1秒。

“運行主進程(%s)。”% (os.getpid())

MainStart = time.time() #記錄主進程開始的時間。

p =池(8)?#打開進程池

對於範圍內的I(16):#打開14進程。

P.apply _ async (run_proc,args = ('process'+str (i),)#每個進程都調用run_proc函數。

#args表示傳遞給函數的參數。

打印“正在等待所有子流程完成...”

P.close() #關閉進程池。

p.join()?#在主進程繼續執行之前,等待所有打開的進程被執行。

打印“所有子流程完成”

mainEnd = time.time()?#記錄主流程的結束時間

打印'所有進程運行了%0.2f秒'% (mainEnd-mainStart)?#主進程執行時間123456789101213141516161665438。

實施結果:?

開始部分

運行主流程(30920)。?

正在等待所有子流程完成…?

運行子進程Process0 (32396)?

運行子進程Process3 (25392)?

運行子進程Process1 (28732)?

運行子進程Process2 (32436)

最後壹部分:

運行子進程Process15 (25880)?

所有子流程都完成了嗎?

所有過程持續2.49秒。

相關說明:

這裏,並發進程的數量被進程池限制為8個,當程序運行時,將生成16個進程。進程池將自動管理系統中的並發進程數,其余的將在隊列中等待。並發進程的數量是有限的,因為系統中並發進程越多越好。過多的並發進程可能會使CPU將大部分時間花在進程調度上,而不是執行有效的計算。

當采用多進程並發技術時,就單個處理器而言,其進程的執行是串行的。而在某個時刻(比如執行結果的開始,每個進程的執行順序是不確定的),哪個進程獲得CPU資源並執行是不可預測的,這就體現了進程的異步性。

如果單個程序執行run_proc函數14次,至少需要16秒。通過進程的並發,只需要2.49秒,可見並發的優勢。