2014-10-09 87 views
1

我有一個無限循環運行異步,但我無法終止它。這裏是我的代碼的類似版本:Python多處理異步無法終止進程

from multiprocessing import Pool 
test_pool = Pool(processes=1) 
self.button1.clicked.connect(self.starter) 
self.button2.clicked.connect(self.stopper) 

    def starter(self): 
     global test_pool 
     test_pool.apply_async(self.automatizer) 

    def automatizer(self): 
     i = 0 
     while i != 0 : 
      self.job1() 
      # safe stop point 
      self.job2() 
      # safe stop point 
      self.job3() 
      # safe stop point 

    def job1(self): 
     # doing some stuff 


    def job2(self): 
     # doing some stuff 


    def job3(self): 
     # doing some stuff 


    def stopper(self): 
     global test_pool 
     test_pool.terminate() 

我的問題是終止()內塞功能不起作用。我試着把job1,job2,job3中的terminate()函數仍然不工作,試着把它放在starter函數的循環結尾,再次不起作用。我怎樣才能阻止這個異步過程?

在任何時候停止進程都足夠好,是否有可能讓它停在我想要的點上?我的意思是如果一個停止命令(不知道它是什麼命令)給予處理,我希望它完成「#安全停止點」標記的步驟,然後終止該過程。

+0

這似乎很奇怪:'i = 0'後面跟着'while i!= 0:'因爲我設置爲零,while語句永遠不會循環 – 2014-10-09 06:27:23

+0

發佈您正在使用的實際代碼。你發佈的是*不是一個有效的Python程序。 – Bakuriu 2014-10-09 06:57:26

+0

你不需要'Pool'來啓動一個任務;一個'進程'就足夠了。 – 2014-10-09 07:28:38

回答

1

你真的應該避免在正常操作中使用terminate()。它只能用於不尋常的情況,例如掛起或無響應的過程。結束進程池的正常方法是調用pool.close(),然後再調用pool.join()

這些方法確實需要您的池正在執行的函數返回,並且您對pool.join()的調用將阻止您的主進程,直到它爲止。我建議你添加一個multiprocess.Queue給自己一個方法來告訴你的子進程退出:

# this import is NOT the same as multiprocessing.Queue - this is here for the 
# queue.Empty exception 
import Queue 

queue = multiprocessing.Queue() # not the same as a Queue.Queue() 

def stopper(self): 
    # don't need "global" keyword to call a global object's method 
    # it's only necessary if we want to modify a global 
    queue.put("Stop") 
    test_pool.close() 
    test_pool.join() 

def automatizer(self): 
    while True: # cleaner infinite loop - yours was never executing 
     for func in [self.job1, self.job2, self.job3]: # iterate over methods 
      func() # call each one 

      # between each function call, check the queue for "poison pill" 
      try: 
       if queue.get(block=False) == "Stop": 
        return 
      except Queue.Empty: 
       pass 

既然你沒有提供一個更完整的代碼示例,你必須找出其中實際實例化multiprocessing.Queue以及如何傳遞信息。另外,Janne Karila的評論是正確的。無論如何,如果您一次只使用一個進程,則應該將代碼切換爲使用單個Process而不是池。 Process類也使用阻止join()方法告訴它一旦返回就結束。在「已知安全點」結束進程的唯一安全方法是實現某種進程間通信,就像我在這裏所做的那樣。管道也可以工作。