我有一个无限循环运行异步但我无法终止它。这是我的代码的类似版本:
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”标记的步骤然后终止该过程。
答案 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()
方法告诉它在返回后结束。在“已知安全点”结束进程的唯一安全方法是实现某种类似的进程间通信,就像我在这里所做的那样。管道也可以。