2017-08-31 83 views
5

我目前正在从Linux移植一个Python项目到Windows(使用Anaconda Python 3.6)。一切正常,我只是无法顺利退出asyncio循环。在Windows中asyncio循环的add_signal_handler()

在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中,不幸的是我得到了NotImplementedErroradd_signal_handler。没有这个,当然我从来没有机会彻底关闭程序。

关于如何解决这个问题的任何想法?谢谢。

+0

请参阅[问题23057](http://bugs.python.org/issue23057)。 – eryksun

回答

3

Windows没有信号。

如果通过TerminateProcess API终止进程,则不会有任何清理机会(就像'kill -9'一样,将流程吹走)。

但是windows有两种方法可以告诉你的代码是否应该退出,一个用于控制台程序(例如python.exe)和一个用于gui程序(pythonw.exe)。

Python会自动处理控制台事件并引发KeyboardInterrupt异常,但您可以使用控制台控制处理程序API(https://docs.microsoft.com/en-us/windows/console/console-control-handlers)将自己的代码挂接到该处理程序中,但那可能是过度杀毒。只需在您的事件循环中设置适当的异常处理程序。

对于GUI进程,Windows向您发送Windows消息,如WM_QUIT或其他各种其他用户,如果用户注销,系统进入省电模式等,您也可以在ctypes或win32软件包的帮助下处理这些消息,或许多python gui库中的任何一个。

+0

谢谢。这就是我所害怕的。我想最简单的方法是为Windows添加一个简单的GUI ... –

+1

@The_Fallen,你是否尝试在问题23057中添加定期任务的建议? @schlenk,C运行时有一个控制台控制处理程序,为其他事件引发“SIGINT”,Ctrl + C和“SIGBREAK”。 KeyboardInterrupt来自Python的默认处理程序,但可以替换它。对于asyncio,'signal.set_wakeup_fd'已更新为支持Windows上的套接字,但出于某种原因,在Windows事件循环中实现信号处理程序的修补程序从未最终完成并合并。我不使用asyncio,所以我没有理由拿起地幔。 – eryksun

+0

不,我没有,我现在只是使用pyqt添加一个简单的窗口。像魅力一样工作,当我关闭窗户时,循环很好地结束。不过谢谢。 –