這段python多進程百思不得其解,求大神指點問題何在?

下面是我寫的一段,三個進程,每個在上一個進程開始一段時間後開始,交替進行,用multiprocessing包的Array進行進程間通信,但輸出中存在自己無法解釋的問題,有一些後一個進程的StartTime1 比前一個進程的StartTime2小,難道程序中對於loop_info的改變在第一次time.sleep還沒結束就已經完成了嗎?

補充:發現是mainstart的值在浮動,然而。。它為什麼會浮動呢。。

補充2:猜想應該是子進程在建立的時候會重新初始化一遍主進程的初始值,每建立一個新的進程都會產生一個新的mainstart,把參數直接傳到類裡面就沒事了。。應該是這樣吧?

from multiprocessing import Process, Array, Value
import time

mainstart = time.time()
class TestProcess(Process):
def __init__(self, loop_info,number,loop_time):
Process.__init__(self)
self.loop_info = loop_info
self.number = number
self.loop_time = loop_time
self.daemon = True

def run(self):
while(True):
if(self.loop_info[self.number-1]):
starttime1 = round(time.time()-mainstart,4)
time.sleep(self.loop_time/len(self.loop_info))
starttime2 = round(time.time()-mainstart,4)
self.loop_info[self.number] = 1
self.loop_info[self.number-1] = 0
time.sleep(0.02)
print("Number{0} StartTime1:{1} | StartTime2:{2}".format(self.number, starttime1,starttime2))

if __name__ == "__main__":
loop_info = Array("i",[0,0,1])
loop_time = 0.2
process1 = TestProcess(loop_info, 0, loop_time)
process2 = TestProcess(loop_info, 1, loop_time)
process3 = TestProcess(loop_info, 2, loop_time)
process1.start()
process2.start()
process3.start()
process1.join()
process2.join()
process3.join()

下面是輸出結果:

Number0 StartTime1:0.03 | StartTime2:0.0971

Number1 StartTime1:0.0961 | StartTime2:0.1632

Number2 StartTime1:0.1672 | StartTime2:0.2343

Number0 StartTime1:0.2312 | StartTime2:0.2984

Number1 StartTime1:0.2974 | StartTime2:0.3645

Number2 StartTime1:0.3685 | StartTime2:0.4357

Number0 StartTime1:0.4326 | StartTime2:0.4997

Number1 StartTime1:0.4987 | StartTime2:0.5658

Number2 StartTime1:0.5698 | StartTime2:0.6374

Number0 StartTime1:0.6343 | StartTime2:0.7019


只是猜想。題主您用的是 Windows?

17.2. multiprocessing - Process-based parallelism - Python 3.6.0 documentation

注意這段 Contexts and start methods 提到的三種不同的啟動模式。

如果你是 macOS 或者 Linux,默認用 fork 模式啟動的話,子進程會複製一遍父進程(最初的 python 程序)的內存,並從 fork 的位置繼續執行,所以 mainstart 應該是一致的。

如果是 Windows,則 multiprocessing 用 spawn 啟動子進程,time.time() 在每個子進程被調用一次。所以您的「浮動」應該是說三個子進程的 mainstart 值有可能不同,以及都比主進程的值為晚。

如果是這樣,那麼解法就是您自己提到的,把最初求好的 mainstart 傳進去就好。

注意這裡要修改您的 TestProcess.__init__,接受 target 和 args 參數以啟動一個特定的函數。

更簡單的應該是 TestProcess(object),def MakeTestProcess(xxx) 然後在外面 Process(target=MakeTestProcess, args=(loop_info, mainstart))...

—— Python 在這組 API 里真是做了不少黑魔法啊……


推薦閱讀:

運行過程中程序中的變數存儲在哪?
C++中已經有面向對象的概念,那struct還有啥存在的意圖?
Python模塊如何安裝 並確認模塊已經安裝好?
在編程中有沒有巧妙運用數學知識解決過問題?
如何看待波格契夫2015年5月左右研發病毒入侵中國進行比特幣敲詐?

TAG:Python | 編程 | Python3x | Python使用技巧 | Python開發 |