首頁 >後端開發 >Python教學 >基於python的多進程共享變數正確開啟方式

基於python的多進程共享變數正確開啟方式

不言
不言原創
2018-04-28 15:55:292938瀏覽

下面為大家分享一篇基於python的多進程共享變數正確開啟方式,具有很好的參考價值,希望對大家有幫助。一起過來看看吧

多進程共享變數和獲得結果

由於工程需求,要使用多執行緒來執行一個程式。但因為聽說python的多執行緒是假的,所以使用多進程,反正任務需要共享的參數少。

查閱資料,發現實作多重流程主要使用Multiprocessing,有兩種方式,一種是Process,另一種是Pool。


p = Process(target=fun,args=(args))


再透過p.start()來啟動一個子進程,透過p.join()方法讓子進程運行結束後再執行父進程。

但是這樣很煩,還要寫個for 迴圈來開n個執行緒和join。

於是推薦用Pool。它可以開啟一個固定大小的行程池,然後每個執行緒執行apply_async()函數呼叫要執行的函數,最後再close和join。

程式碼如下:


#
pathm=Manager().Queue(len(pathlist))
for d in pathlist:
 pathm.put(d)
p=Pool(cp.threads)
results=[]
for i in range(cp.threads):
 temp=p.apply_async(ProcessWorker,args=(i,pathm,cp))
 results.append(temp)
print 'Waiting for all subprocesses done...'
p.close()
p.join()
print 'All subprocesses finish Processing.'
results=[r.get() for r in results]


上面的程式碼示範如何使用pool多進程,如何在Pool裡的進程之間共用變數pathm,以及如何取得進程函數執行的結果。需要注意的是,ProcessWorker必須是個無界的函數,否則報錯該函數無法被pickle從而不能分配到各個進程。


cPickle.PicklingError: Can&#39;t pickle <type &#39;instancemethod&#39;>: attribute lookup __builtin__.instancemethod failed


#有界函數與python的多進程機制



從上面引申到了一個概念,就是有界函數無界函數的概念。

查閱資料之後我總結如下:

##########有界函數是包在一個類別中,並且只有當類別被實例化之後才能所使用的函數,它的界就是這個實例。我們常常把這些函數稱為類別方法。例如以self為參數的類別方法。 ######無界函數可以是沒有被包在類別中的函數,也可以是類別中的靜態方法,它們跟類別是獨立的。如類別中的靜態方法,它即使在某個類別中被定義,但是不能存取類別中的參數和其他方法。 ######python多進程的機制應該是把每個行程要呼叫的方法和傳入的參數(如上面例子中的ProcessWorker)編譯然後打包,然後複製到每個進程中執行。如果輸入的是一個有界函數,那麼它的參數應該是它所屬的類別(包括參數和方法),但是這是無法獲得的,而且類別屬性和方法可能會有坑,導致難以打包。所以python限定了多進程要呼叫的函數不能是類別方法。 ######我們要把多進程呼叫的函數放到類別外面,或是變成靜態函數。但是靜態函數的話不能被所屬的類別的方法調用(self.ProcessWorker的形式),需要在外部調用,如mc=MyClass(),mc.ProcessWorker來調用,或者MyClass().ProcessWorker來調用。 ######相關推薦:############基於Python 裝飾器裝飾類別中的方法############基於Python Numpy的陣列array和矩陣matrix詳解_python############################

以上是基於python的多進程共享變數正確開啟方式的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn