Python多处理异步无法终止进程

时间:2014-10-09 06:18:25

标签: python multithreading asynchronous terminate

我有一个无限循环运行异步但我无法终止它。这是我的代码的类似版本:

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()

我的问题是终止()内部塞子功能不起作用。我试图将terminate()放在job1,job2,job3函数仍然无法正常工作,尝试在启动函数的循环结束时,再次无法正常工作。如何停止此异步过程?

虽然在任何时候停止这个过程都足够好,是否有可能让它停在我想要的位置?我的意思是如果一个停止命令(不确定它是什么命令)被给予处理,我希望它完成“#safe stop point”标记的步骤然后终止该过程。

1 个答案:

答案 0 :(得分: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()方法告诉它在返回后结束。在“已知安全点”结束进程的唯一安全方法是实现某种类似的进程间通信,就像我在这里所做的那样。管道也可以。