Windows中asyncio循环的add_signal_handler()

2024-05-21 00:58:47 发布

您现在位置:Python中文网/ 问答频道 /正文

我目前正在将一个Python项目从Linux移植到Windows(使用anacondapython3.6)。一切都工作得很好,我只是无法顺利地退出asyncio循环。在

在Linux中,我执行以下操作:

class GracefulExit(SystemExit):
    code = 1

def raise_graceful_exit():
    raise GracefulExit()

loop = asyncio.get_event_loop()
loop.add_signal_handler(signal.SIGINT, raise_graceful_exit)
loop.add_signal_handler(signal.SIGTERM, raise_graceful_exit)

try:
    loop.run_forever()
except GracefulExit:
    pass

shutdown()

在Windows中,不幸的是我在add_signal_handler上得到了NotImplementedError。如果没有这个,我当然没有机会彻底关闭程序。在

有什么办法解决这个问题吗?谢谢。在


Tags: 项目loopaddasynciosignallinuxwindowsexit
2条回答

Windows没有信号。在

如果进程通过terminateProcessAPI被终止,那么您就没有机会进行清理(它类似于'kill-9',会让您的进程崩溃)。在

但是windows有两种方式来通知你的代码是否应该退出,一种是针对控制台程序(例如。python.exe)还有一个是gui程序(pythonw.exe). 在

Python会自动处理控制台事件并引发一个键盘中断异常,但是您可以使用控制台控制处理程序api(https://docs.microsoft.com/en-us/windows/console/console-control-handlers)将自己的代码挂接到该处理程序中,但这样做可能有点过头了。只需在事件循环中设置一个适当的异常处理程序。在

对于GUI进程,Windows向您发送Windows消息,如WM_QUIT或其他各种消息如果用户注销、系统进入节能模式等等,您也可以在cypes或win32包或许多python GUI库的帮助下处理这些消息。在

实际上,你可以在你的python脚本中实现一种跨平台的python信号处理程序,它可以在Unix/Linux和Windows上运行,python有一个标准的信号库,所以可以这样做

import asyncio
import signal


class GracefulExit(SystemExit):
    code = 1


def raise_graceful_exit(*args):
    loop.stop()
    print("Gracefully shutdown")
    raise GracefulExit()


def do_something():
    while True:
        pass


loop = asyncio.get_event_loop()
signal.signal(signal.SIGINT, raise_graceful_exit)
signal.signal(signal.SIGTERM, raise_graceful_exit)

try:
    loop.run_forever(do_something())
except GracefulExit:
    pass
finally:
    loop.close()

由于前面提到的平台差异,它在Windows和Linux上的行为并不完全相同,但在大多数情况下,它在两个平台上都可以正常工作。在

相关问题 更多 >