2015-11-25 30 views
0

我正在玩玩具多處理問題,並且事件信號不能按預期工作。多處理文檔將Event()的詳細描述引用到多線程文檔中,並且這些方法的描述正是我想要做的。我想要由父類生成的工作進程(從multiprocessing.Process中分類),然後等待父類的啓動信號,完成它們的工作,然後終止。然而,似乎正在發生的事情是,第一個流程一旦運行就會阻止其他流程。這裏發生了什麼,我該如何解決?Python多處理:Event.wait()阻止其他進程

class Worker(Process): 

    def __init__(self, my_id, caller): 
     Process.__init__(self) 
     self.caller = caller 
     self.my_id = my_id 

    def run(self): 
     print("%i started"%self.my_id) 
     self.caller.start_flag.wait() 
     print("%i sleeping"%self.my_id) 
     sleep(2000) 


class ParentProcess(object): 

    def __init__(self, num_procs): 
     self.procs = [] 
     self.start_flag = Event()   
     for i in range(num_procs): 
      self.procs.append(Worker(i, self)) 

    def run(self): 
     for proc in self.procs: 
      proc.run() 
     self.start_flag.set() 
     for proc in self.procs: 
      proc.join() 
      print("%i done"%proc.my_id)   


if __name__ == '__main__': 
    cpus = cpu_count()  
    world = ParentProcess(cpus) 
    start = time() 
    world.run() 
    end = time() 
    runtime = end - start 
    print("Runtime: %3.6f"%runtime) 

這只是輸出「0開始」,然後掛起。看起來Event.wait()阻塞了所有其他線程,甚至是調用者。文件暗示這不應該發生。

+0

'start'啓動過程,而不是'run'。 'start'安排'run'在新過程中被調用。 – user2357112

回答

1

他是代碼的工作版本。當你繼承子進程時,你需要實現run方法來定義在該進程中應該運行的內容。當你真的希望進程啓動時,你應該調用它的啓動方法(proc.start())。

from multiprocessing import Process, Event 
from time import time, sleep 

class Worker(Process): 

    def __init__(self, my_id, caller): 
     Process.__init__(self) 
     self.caller = caller 
     self.my_id = my_id 

    def run(self): 
     print("%i started"%self.my_id) 
     self.caller.start_flag.wait() 
     print("%i sleeping"%self.my_id) 
     sleep(5) 


class ParentProcess(object): 

    def __init__(self, num_procs): 
     self.procs = [] 
     self.start_flag = Event()   
     for i in range(num_procs): 
      self.procs.append(Worker(i, self)) 

    def run(self): 
     for proc in self.procs: 
      proc.start() 
     self.start_flag.set() 
     for proc in self.procs: 
      proc.join() 
      print("%i done"%proc.my_id)   


if __name__ == '__main__': 
    cpus = 4 
    world = ParentProcess(cpus) 
    start = time() 
    world.run() 
    end = time() 
    runtime = end - start 
    print(runtime) 

輸出:

0 started 
1 started 
2 started 
2 sleeping 
0 sleeping 
1 sleeping 
3 started 
3 sleeping 
0 done 
1 done 
2 done 
3 done 
5.01037812233 
+0

謝謝,我之前嘗試過start()而不是run(),但由於某種原因,在我的機器上它沒有任何作用,然後一次性吐出所有輸出到控制檯......不知道它爲什麼會這樣做那。我想我過早地終止了這個計劃,認爲它掛了。 – strangeintp

+0

每當你打電話打印嘗試把打印(...,flush = True)。這將強制輸出被刷新到屏幕而不是被緩衝 - 這種方法需要python 3.3+ –