我正在开发一个使用python3.4的asyncio进行网络连接的应用程序。当此应用程序干净地关闭时,节点需要与集线器“断开连接”。此断开连接是一个需要网络连接的活动进程,因此循环需要在关闭之前等待此操作完成。
我的问题是使用协同程序作为信号处理程序将导致应用程序不关闭。请考虑以下示例:
import asyncio
import functools
import os
import signal
@asyncio.coroutine
def ask_exit(signame):
print("got signal %s: exit" % signame)
yield from asyncio.sleep(10.0)
loop.stop()
loop = asyncio.get_event_loop()
for signame in ('SIGINT', 'SIGTERM'):
loop.add_signal_handler(getattr(signal, signame),
functools.partial(ask_exit, signame))
print("Event loop running forever, press CTRL+c to interrupt.")
print("pid %s: send SIGINT or SIGTERM to exit." % os.getpid())
loop.run_forever()
如果您运行此示例然后按Ctrl + C,则不会发生任何事情。 问题是,如何使用siganls和coroutines来实现这种行为?
答案 0 :(得分:9)
python的语法> = 3.5
loop = asyncio.get_event_loop()
for signame in ('SIGINT', 'SIGTERM'):
loop.add_signal_handler(getattr(signal, signame),
lambda: asyncio.ensure_future(ask_exit(signame)))
答案 1 :(得分:4)
loop = asyncio.get_event_loop()
for signame in ('SIGINT', 'SIGTERM'):
loop.add_signal_handler(getattr(signal, signame),
asyncio.async, ask_exit(signame))
这样信号会导致你的ask_exit被安排在任务中。
答案 2 :(得分:1)
python3.8
async def handler_shutdown
,并在传递给loop.create_task()
时将其包裹在add_signal_handler()
中def handler_shutdown()
使用异步。functools.partial()
import asyncio
import functools
def handler_shutdown(signal, loop, tasks, http_runner, ):
...
...
def main():
loop = asyncio.get_event_loop()
for signame in ('SIGINT', 'SIGTERM', 'SIGQUIT'):
print(f"add signal handler {signame} ...")
loop.add_signal_handler(
getattr(signal, signame),
functools.partial(handler_shutdown,
signal=signame, loop=loop, tasks=tasks,
http_runner=http_runner
)
)
我遇到的主要问题是错误
raise TypeError("coroutines cannot be used "
通过将例程包装在loop.create_task()