Обработка сигналов в потоках Python

У меня есть многопоточное приложение, написанное на Python, и при получении прерывания через Ctrl+C или иногда через kill приложение зависает. Трассировка стека представлена ​​из одного потока, но приложение остается на переднем плане, и мне обычно приходится переводить его в фоновый режим с помощью Ctrl+Z, затем попытаться убить его.

Каков правильный способ обработки сигналов и прерываний клавиатуры внутри многопоточного приложения?


person Eric Pruitt    schedule 06.01.2011    source источник


Ответы (4)


Если вы установите newthread.daemon = True перед запуском каждого потока, потоки будут автоматически уничтожены при выходе из основного потока. Это не совсем то, о чем вы спрашивали, но из того, что вы описали, похоже, что это стоит знать.

person Thomas K    schedule 06.01.2011
comment
Тогда, я полагаю, возникает вопрос, получает ли основной поток Ctrl+C и другие сигналы по умолчанию? EDIT: На этот вопрос отвечает сообщение @shanked. - person Eric Pruitt; 07.01.2011
comment
просто помните: потоки демона резко останавливаются при завершении работы. Их ресурсы (такие как открытые файлы, транзакции базы данных и т. д.) могут не освобождаться должным образом. docs.python.org/2/library/threading.html и docs.python.org/3.4/library/threading.html - person kkurian; 05.03.2015

Способ, которым я работал над этой проблемой, состоял в том, чтобы создать модуль, который мог бы хранить список потоков. В модуле также был метод, убивавший все потоки в этом списке. Я зарегистрировал этот метод для вызова при получении сигнала SIGINT. Наконец, я создал класс-оболочку для Thread, который автоматически добавлял бы созданный экземпляр в список потоков.

person unholysampler    schedule 06.01.2011
comment
1) Не знал, что он существует. 2) Оболочка Thread уже существовала для некоторых других вещей, которые не имели отношения к этому вопросу. При этом процесс остается прежним. - person unholysampler; 07.01.2011

Обработка потоков CPython: прерывание описывает, что происходит с сигналами в потоках Python, и различные решения вашей проблемы. Это хорошее чтение.

person brildum    schedule 06.01.2011

Используйте модуль сигнала и продолжайте читать здесь Обработчики сигналов и ведение журнала в Python о возможных подводных камнях.

Чтобы перехватить Ctrl+C действия пользователя, вам необходимо использовать обработчик signal для SIGINT .

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

person Raphael Bossek    schedule 06.01.2011
comment
Я не знал о взаимодействии (или невзаимодействии) GIL с сигналами. Это объясняет некоторые модели поведения, с которыми я столкнулся. - person Eric Pruitt; 07.01.2011