2014-10-09 99 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()方法告诉它一旦返回就结束。在“已知安全点”结束进程的唯一安全方法是实现某种进程间通信,就像我在这里所做的那样。管道也可以工作。