Как определить причину в Python кода, который нельзя прервать с помощью CTRL + C

Я использую запросы, чтобы вытащить некоторые файлы. Я заметил, что программа зависает после большого количества итераций, которое варьируется от 5 до 20 тысяч. Я могу сказать, что он висит, потому что папка, в которой хранятся результаты, не менялась в течение нескольких часов. Я пытался прервать процесс (я использую IDLE), нажав CTRL + C, но безрезультатно. Я хотел бы прервать, а не убивать процесс, потому что перезапуск проще. В конце концов мне пришлось убить процесс. Я перезагружаю, и он снова работает нормально, пока у меня не появятся те же симптомы. Я хотел бы выяснить, как диагностировать проблему, но, поскольку мне приходится убивать все, я понятия не имею, с чего начать.

Есть ли альтернативный способ просмотра происходящего или более надежного прерывания процесса?

Я предполагал, что если я могу прервать, не убивая, я могу посмотреть глобальные переменные и/или сделать что-то еще, чтобы выяснить, где висит мой код.


person PyNEwbie    schedule 06.04.2013    source источник
comment
Я столкнулся с этой проблемой, когда программа использует потоки. Основной поток умирает, но все остальные потоки остаются в живых, а KeyboardInterrupt некуда деваться, поэтому он остается в живых. Ваша программа многопоточная?   -  person icktoofay    schedule 07.04.2013
comment
Нет, по крайней мере, не мной запросы могут быть перенаправлены, я не уверен, что мне придется его сканировать.   -  person PyNEwbie    schedule 07.04.2013
comment
На какой платформе вы работаете?   -  person Ned Deily    schedule 07.04.2013
comment
Win 7 64 бит Python 2.7.1   -  person PyNEwbie    schedule 07.04.2013


Ответы (1)


Если еще не поздно: я только что столкнулся с теми же проблемами и могу дать несколько советов.

Во-первых: в python большинство ожидающих apis не прерываемы (например, Thread.join(), Lock.acquire()...). Посетите эти страницы для получения дополнительной информации: http://snakesthatbite.blogspot.fr/2010/09/cpython-threading-interrupting.html http://docs.python.org/2/library/thread.html

Затем, если поток ожидает такого вызова, его нельзя остановить. Есть еще одна вещь, которую нужно знать: если обычный поток работает (или зависает), основная программа будет оставаться неопределенно долго, пока все потоки не будут остановлены или процесс не будет убит.

Чтобы избежать этого, вы можете сделать поток потоком демона: Thread.daemon=True перед вызовом Thread.start().

Во-вторых, чтобы найти, где зависла ваша программа, вы можете запустить ее с помощью отладчика, но я предпочитаю ведение журнала, потому что журналы всегда есть на случай, если уже поздно отлаживать.

Попробуйте вести журнал до и после каждого ожидающего вызова, чтобы увидеть, сколько времени ваши темы были зависшими. Чтобы иметь высококачественные журналы, используйте ведение журнала python, настроенное с обработчиком файлов, обработчиком html или, что еще лучше, с обработчиком системного журнала.

person gotrunk    schedule 09.05.2013