2017-08-31 28 views
5

Tôi hiện đang chuyển một dự án Python từ Linux sang Windows (sử dụng Anaconda Python 3.6). Tất cả mọi thứ hoạt động hoàn hảo, tôi chỉ không thể có được một lối ra duyên dáng của vòng lặp asyncio làm việc.add_signal_handler của asyncio loop() trong Windows

Trong Linux Tôi đang làm như sau:

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() 

Trong Windows, tiếc là tôi có được một NotImplementedError trên add_signal_handler. Nếu không có điều này, tất nhiên tôi không bao giờ có cơ hội để tắt chương trình.

Bất kỳ ý tưởng nào về cách giải quyết vấn đề này? Cảm ơn.

+0

Xem [issue 23057] (http://bugs.python.org/issue23057). – eryksun

Trả lời

3

Windows không có tín hiệu.

Nếu quá trình bị giết qua API TerminateProcess, bạn không có cơ hội để dọn dẹp (giống như 'kill -9', thổi quá trình của bạn đi).

Nhưng cửa sổ có hai cách để báo hiệu nếu mã của bạn nên thoát, một cho các chương trình điều khiển (ví dụ: python.exe) và một cho chương trình gui (pythonw.exe).

Python tự động xử lý điều khiển và tăng ngoại lệ KeyboardInterrupt, nhưng bạn có thể móc mã của riêng bạn vào trình xử lý đó bằng API xử lý điều khiển bàn điều khiển (https://docs.microsoft.com/en-us/windows/console/console-control-handlers), nhưng đó có thể là quá mức cần thiết. Chỉ cần thiết lập một trình xử lý ngoại lệ thích hợp trên vòng lặp sự kiện của bạn.

Đối với quy trình GUI, Windows sẽ gửi cho bạn các thông báo cửa sổ, như WM_QUIT hoặc nhiều thứ khác nếu người dùng đăng xuất, hệ thống chuyển sang chế độ tiết kiệm năng lượng, v.v. với sự trợ giúp của ctypes hoặc gói win32, hoặc bất kỳ của nhiều libs gui python.

+0

Cảm ơn. Đó là điều tôi sợ. Tôi đoán cách dễ nhất là thêm một giao diện đơn giản chỉ dành cho Windows ... –

+1

@The_Fallen, bạn đã thử đề xuất trong vấn đề 23057 để thêm một nhiệm vụ định kỳ? @schlenk, thời gian chạy C có trình điều khiển điều khiển bảng điều khiển tăng 'SIGINT' cho Ctrl + C và' SIGBREAK' cho các sự kiện khác. 'KeyboardInterrupt' là từ trình xử lý mặc định của Python, nhưng bạn có thể thay thế nó. Đối với asyncio, 'signal.set_wakeup_fd' đã được cập nhật để hỗ trợ ổ cắm trên Windows, nhưng vì lý do nào đó, bản vá để triển khai trình xử lý tín hiệu trong vòng lặp sự kiện Windows chưa bao giờ được hoàn thành và hợp nhất. Tôi không sử dụng asyncio, vì vậy tôi đã không có một lý do để chọn lên lớp áo. – eryksun

+0

Không, tôi đã không, tôi bây giờ chỉ cần thêm một cửa sổ đơn giản bằng cách sử dụng pyqt. Làm việc như một nét duyên dáng và vòng lặp kết thúc độc đáo khi tôi đóng cửa sổ. Nhưng dù gì cũng cảm ơn. –