Python 父进程使用asynio.add\u signal\u处理程序捕获子进程的终止信号
我有一个asyncio事件循环,我使用Python 父进程使用asynio.add\u signal\u处理程序捕获子进程的终止信号,python,multiprocessing,signals,python-asyncio,Python,Multiprocessing,Signals,Python Asyncio,我有一个asyncio事件循环,我使用loop.add\u signal\u handler()向其中添加了一个信号处理程序。我想要捕捉的信号是SIGINT、SIGHUP和SIGTERM,以优雅地关闭我的事件循环 从这个事件循环中,我想使用multiprocessing.Process()来分叉进程。此过程p我希望能够使用p.terminate()从事件循环终止。但是,信号处理程序将捕获由p.terminate()发出的SIGTERM信号,提示执行我的关机代码,使p保持运行 我还没有找到任何解决
loop.add\u signal\u handler()
向其中添加了一个信号处理程序。我想要捕捉的信号是SIGINT、SIGHUP和SIGTERM,以优雅地关闭我的事件循环
从这个事件循环中,我想使用multiprocessing.Process()
来分叉进程。此过程p
我希望能够使用p.terminate()
从事件循环终止。但是,信号处理程序将捕获由p.terminate()
发出的SIGTERM信号,提示执行我的关机代码,使p
保持运行
我还没有找到任何解决办法。大多数帖子说,你应该避免使用终止信号,通过传递例如None
来尝试使用multiprocessing.Queue()
,并在子进程中处理。虽然我看到了这种方法的有用性和简洁性,但在我的例子中,使用多处理.Queue()
将是不可行的。我是在尝试不可能的事情还是错过了什么
我创建了一个最低限度的示例:
import asyncio
import multiprocessing as mp
import signal
import time
class Test():
def __init__(self):
self.event_loop = asyncio.get_event_loop()
def create_mp(self):
# Wrapper for creating process
self.p = mp.Process(target=worker)
self.p.start()
async def shutdown_mp(self):
# Shutdown after 5 sec
await asyncio.sleep(5)
self.p.terminate()
async def async_print(self):
# Simple coroutine printing
while True:
await asyncio.sleep(1)
print("Async_test")
async def shutdown_event_loop(self, signal):
# Graceful shutdown, inspiration from roguelynn (Lynn Root)
print("Received exit signal {}".format(signal.name))
tasks = [t for t in asyncio.all_tasks() if t is not asyncio.current_task()]
# Cancel all tasks
[task.cancel() for task in tasks]
print("Cancelling {} outstanding tasks".format(len(tasks)))
await asyncio.gather(*tasks, return_exceptions=True)
self.event_loop.stop()
def run(self):
# Add signals
signals = (signal.SIGINT, signal.SIGHUP, signal.SIGTERM)
for s in signals:
self.event_loop.add_signal_handler(
s, lambda s=s: self.event_loop.create_task(self.shutdown_event_loop(s)))
# Schedule async task
self.event_loop.create_task(self.async_print())
# Start processes
self.create_mp()
# Schedule process to be terminated
self.event_loop.create_task(self.shutdown_mp())
self.event_loop.run_forever()
def worker():
# Simple process
while True:
print("Test")
time.sleep(1)
if __name__ == "__main__":
test = Test()
test.run()
我无法简单地
键盘中断
取消进程。相反,我使用pgrep python3
和kill-9pid
这不起作用,因为事件循环用于与其信号处理程序通信的内部管道最终在父级和子级之间共享,导致父级收到子级中实际发生的信号的通知<默认情况下,code>mp.Processfork,并且不支持在fork()之后重用事件循环。看,也许有帮助。