Проблема с исключениями KeyboardInterrupt и IOError
В цикле while у меня идет парсинг сайтов черезе библиотеку grab . Периодически вылетает ошибка от grab , которая имеет тип исключения IOError . Я её поймал. С этим проблем нет. Но мне требуется так же завершать цикл, нажатием CTRL + C . Но в результате нажатия CTRL + C , вылетает ошибка KeyboardInterrupt , но цикл продолжается дальше.
while line: try: bla bla bla except IOError: line = line except KeyboardInterrupt: break else: line = base_file.readline()
Отслеживать
9,209 1 1 золотой знак 26 26 серебряных знаков 48 48 бронзовых знаков
Обработка KeyboardInterrupt (Ctrl+C)
Как я могу, в pythone, и могу ли вообще, обработать нажатие Ctrl+C, остановку скрипта. а именно, не выплевывать нечто вроде:
$ ./arhan ^CTraceback (most recent call last): File "./arhan", line 68, in while True: KeyboardInterrupt
А писать нормальное сообщение, о том, что работа остановлена. или вообще ничего не писать.
VirRaa ★★★
08.02.13 12:53:49 MSK

try . except KeyboardInterrupt: .
vden ★★
( 08.02.13 12:56:47 MSK )
Ответ на: комментарий от vden 08.02.13 12:56:47 MSK
Я тоже сначала хотел сделать так, но это придется весь код оборачивать в try. except.
VirRaa ★★★
( 08.02.13 12:58:23 MSK ) автор топика
Ответ на: комментарий от VirRaa 08.02.13 12:58:23 MSK

import sys _old_excepthook = sys.excepthook def myexcepthook(exctype, value, traceback): if exctype == KeyboardInterrupt: print "Handler code goes here" else: _old_excepthook(exctype, value, traceback) sys.excepthook = myexcepthook
vden ★★
( 08.02.13 13:01:37 MSK )
Как правильно завершить работу потоков по KeyboardInterrupt?

A thread can be flagged as a “daemon thread”. The significance of this flag is that the entire Python program exits when only daemon threads are left. The initial value is inherited from the creating thread. The flag can be set through the daemon property or the daemon constructor argument.
Если обработка KeyboardInterrupt сама по себе не нужна, а хотите чтобы процесс по Ctrl+C завершался — объявите все потоки демонами.
Ответ написан более трёх лет назад
Нравится 1 8 комментариев

Андрей Горбик @and_gorbik Автор вопроса
Для данной задачи этот способ наверное действительно хорош, но я хотел бы разобраться с обработкой исключений при использовании потоков (в общем случае).

Сергей Тихонов @tumbler Куратор тега Python
В общем случае
stopped = False while not stopped: try: do_work() except KeyboardInterrupt: stopped = True
Один поток обрабатывать Ctrl+C, триггерит флаг остановки. Остальные потоки замечают этот флаг и тоже останавливаются. Не нашел только сходу в документации, в какой поток прилетает KeyboardInterrupt.

Андрей Горбик @and_gorbik Автор вопроса
Сергей Тихонов, вы не могли бы объяснить, как предложенный Вами способ поможет, если KeyboardInterrupt прилетит в главный поток. Сколько я не пытался сделать код рабочим, так и не смог:
from threading import Thread from time import sleep is_stopped = False def worker(i): global is_stopped while not is_stopped: try: print("worker <>".format(i)) sleep(i) except KeyboardInterrupt: is_stopped = True threads = [Thread(target=worker, args=(i,)) for i in range(1, 4)] for t in threads: t.start() for t in threads: t.join()
При запуске и попытке остановить через ctrl + c ничего не получается.

Сергей Тихонов @tumbler Куратор тега Python
Андрей Горбик, главный поток у Вас не ловит исключения, пока на join сидит. А должен.

Андрей Горбик @and_gorbik Автор вопроса
Сергей Тихонов, все равно не выходит. Ладно, сделал, как вы советовали через демона. Так работает, спасибо.
from threading import Thread from time import sleep def worker(i): while True: print("worker <>".format(i)) sleep(i) threads = [Thread(target=worker, args=(i,), daemon=True) for i in range(1, 4)] for t in threads: t.start() try: for t in threads: t.join() except KeyboardInterrupt: pass

Сергей Тихонов @tumbler Куратор тега Python
Андрей Горбик, ну так основной поток тоже должен стоп-флаг выставлять:
from threading import Thread from time import sleep, time active = True def worker(i): global active while active: try: print(f": worker is active") sleep(i) except KeyboardInterrupt: active = False print(f' worker received SIGINT') threads = [Thread(target=worker, args=(i,)) for i in range(1, 4)] for t in threads: t.start() try: for t in threads: t.join() except KeyboardInterrupt: print(f": main thread received sigint") active = False for t in threads: t.join() print(f": all threads gone")
1541616371.7186885: worker 1 is active 1541616371.718856: worker 2 is active 1541616371.7192252: worker 3 is active 1541616372.7196927: worker 1 is active 1541616372.770136: main thread received sigint 1541616374.7199564: all threads gone

Андрей Горбик @and_gorbik Автор вопроса
Сергей Тихонов, этого я не учел.. Спасибо большое!

Андрей Горбик @and_gorbik Автор вопроса
Сергей Тихонов, заметил, что никогда не печатается строчка «worker received SIGNINT». Мелькнула догадка, что исключение не ловится в воркерах. Убрал обработку в них и все также работает. Видимо, KeyboardInterrupt всегда прилетает в главный поток.
Ответы на вопрос 0
Ваш ответ на вопрос
Войдите, чтобы написать ответ

- Python
- +1 ещё
Почему при большом количестве строк async выдает ошибку?
- 1 подписчик
- 56 минут назад
- 10 просмотров
KeyboardInterrupt
при попытке выполнить Python уходит в бесконечный цыкл,
после прерывания программы пишет:
_Traceback (most recent call last):
______File «C:\python\test.py», line 1794, in
____a =[list(map(int, input().split())) for i in range(m)]
__File «C:\python\test.py», line 1794, in
____a =[list(map(int, input().split())) for i in range(m)]
__File «C:\Users\GENERAL\AppData\Local\Programs\Python\Python310\li b\codecs.py», line 319, in decode
___def decode(self, input, final=False):
KeyboardInterrupt
что там могло сломаться, в программе: генератор списков, цикл и пара пиринтов
попробовал 2 интерпретатора