2017-08-31 90 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添加一個簡單的窗口。像魅力一樣工作,當我關閉窗戶時,循環很好地結束。不過謝謝。 –