我有一个主类,它产生许多子进程,它们是multiprocessing.Process的子类,然后进入无限循环,等待进程被信号中断。
它是从__main__.py文件开始的,如下所示:
from module a import A
import signal
a = A()
def graceful_exit(signal=None, frame=None):
a.stop()
signal.signal(signal.SIGTERM, graceful_exit)
try:
write_pidfile(pid)
a.start()
finally:
graceful_exit()
主类的启动过程如下所示:
def start(self):
# some initialization
for i in range(self.num_workers):
worker = Worker()
self.workers.append(worker)
worker.start()
for w in self.workers:
w.join()
工人没有做任何特别的事情,它只是在一个无限循环中运行一些盲目的工作。
然后是停止方法:
def stop(self):
log.info('waiting for workers to finish')
for w in self.workers:
w.terminate()
现在问题是每当主进程收到一个信号(SIGTERM或SIGINT)时,我得到以下输出:
2016-04-26 12:53:04,651 MainProcess gateway INFO waiting for workers to finish
2016-04-26 12:53:04,653 Worker-1 gateway INFO waiting for workers to finish
2016-04-26 12:53:04,654 Worker-1 gateway INFO waiting for workers to finish
因此:
AttributeError: 'NoneType' object has no attribute 'terminate'
有人可以向我解释为什么子进程正在尝试运行父进程的代码以及如何在主进程中捕获适当的信号并清理工作进程
答案 0 :(得分:0)
在Unix中(我假设您是这样的操作系统),通过分叉当前运行的过程来实现新过程的创建。
新创建的进程(更简单的子进程)将继承所有父进程的文件描述符和信号处理程序。
这意味着在您的示例中,父进程和子进程都将以相同的方式处理传递的SIGTERM信号。
在若干实现中,signals will be delivered to process groups因此导致两个进程都接收到相同的信号。
要解决您的具体问题,只需在您生成孩子的之后在父进程中安装信号处理程序。