5

Vòng lặp while của tôi không thoát khi nhấn Ctrl + C. Dường như bỏ qua ngoại lệ KeyboardInterrupt của tôi. Phần vòng lặp trông giống như sau:python thoát vô hạn trong khi vòng lặp với ngoại lệ KeyboardInterrupt

while True: 
    try: 
    if subprocess_cnt <= max_subprocess: 
     try: 
     notifier.process_events() 
     if notifier.check_events(): 
      notifier.read_events() 
     except KeyboardInterrupt: 
     notifier.stop() 
     break 
    else: 
     pass 
    except (KeyboardInterrupt, SystemExit): 
    print '\nkeyboardinterrupt found!' 
    print '\n...Program Stopped Manually!' 
    raise 

Một lần nữa, tôi không chắc vấn đề là gì nhưng thiết bị đầu cuối của tôi thậm chí không in hai cảnh báo in mà tôi có trong ngoại lệ của mình. Ai đó có thể giúp tôi tìm ra vấn đề này không?

+2

Đầu tiên của bạn 'except KeyboardInterrupt' bắt ngoại lệ. Nó sẽ không được hiển thị cho lần thứ hai 'except (KeyboardInterrupt, SystemExit)' nếu bạn không nâng cấp lại nó. – eumiro

+0

@eumiro - Tôi nhận xét ra KeyboardInterrupt đầu tiên và thay thế các nội dung của ngoại lệ với 'pass' nhưng tôi vẫn gặp vấn đề tương tự. Ctrl + C đang được bỏ qua (ps aux cho thấy quá trình vẫn chạy tốt) – sadmicrowave

+0

@eumiro Tôi cũng đã cố gắng nâng cao lại ngoại lệ KeyboardInterrupt bằng cách thêm 'raise KeyboardInterrupt()' trong 'except KeyboardInterrupt:' đầu tiên vẫn gặp vấn đề tương tự. – sadmicrowave

Trả lời

11

Thay tuyên bố break của bạn với một tuyên bố raise, như dưới đây:

while True: 
    try: 
    if subprocess_cnt <= max_subprocess: 
     try: 
     notifier.process_events() 
     if notifier.check_events(): 
      notifier.read_events() 
     except KeyboardInterrupt: 
     notifier.stop() 
     print 'KeyboardInterrupt caught' 
     raise # the exception is re-raised to be caught by the outer try block 
    else: 
     pass 
    except (KeyboardInterrupt, SystemExit): 
    print '\nkeyboardinterrupt caught (again)' 
    print '\n...Program Stopped Manually!' 
    raise 

Hai báo cáo in trong except khối nên thực hiện với '(một lần nữa)' xuất hiện thứ hai.

+0

Trong khi bạn không hỏi về điều này, câu lệnh 'pass' trong mã của bạn tạo ra cái gọi là spin-lock. Spin-khóa tiêu thụ CPU không cần thiết và có thể tác động đến hiệu năng của toàn bộ hệ thống. Có nhiều cách để tránh chúng. Điều tra bằng cách sử dụng các đối tượng 'Queue.Queue' để giao tiếp giữa các luồng, và' select.select' hoặc mô đun 'multiprocessing' để giao tiếp giữa các tiến trình. – wberry

+0

Vì vậy, nó xảy ra với tôi rằng vấn đề chính của tôi (tôi nghĩ là không liên quan) là tôi đã chia hai kịch bản của tôi hai lần để 'daemonize' nó. Đó là trường hợp, KeyboardInterrupt không còn được kết nối với cùng một thiết bị đầu cuối (tuy nhiên, kịch bản của tôi vẫn sẽ in kết quả đầu ra đến thiết bị đầu cuối đang hoạt động). Có cách nào để vẫn còn sử dụng KeyboardInterrupt (hoặc một cách khác để kết thúc kịch bản của tôi bằng tay) trong một chương trình daemonized? – sadmicrowave

+0

hiện tại tôi đang tìm kiếm processid trong đầu ra 'ps aux' và thi hành' sudo kill [pid] '; tuy nhiên, điều này không làm sạch mã của tôi một cách duyên dáng trước khi giết nó. Tôi cần phải đóng các kết nối cơ sở dữ liệu và loại bỏ đồng hồ inotify trước khi giết chết chương trình. – sadmicrowave

Các vấn đề liên quan