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()
我的问题是,stopper 函数里的 terminate() 不起作用。我试着把 terminate() 放在 job1、job2、job3 函数里,还是不行;又试着把它放在 starter 函数的循环末尾,结果还是不行。我该怎么停止这个异步进程呢?
虽然随时停止这个进程就可以了,但我想知道能不能在我想要的地方停止?我的意思是,如果给进程发一个停止命令(我不太确定这个命令是什么),我希望它能完成到“# 安全停止点”标记的步骤,然后再终止进程。
1 个回答
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()
方法来告诉它在返回后结束。安全结束进程的唯一方法是在“已知安全点”实现某种进程间通信,就像我在这里做的那样。管道也可以用。