Обработка сигналов в Python - PullRequest
       16

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

4 голосов
/ 29 января 2010

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

def SigUSR1Handler(signum, frame):

    self._logger.debug('Received SIGUSR1')

    return

signal.signal(signal.SIGUSR1, SigUSR1Handler)

[signal.signal(signal.SIGUSR1, signal.SIG_IGN)]

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

Может кто-нибудь сказать мне, как это сделать? Может быть, я должен сделать что-то с «рамкой» вручную, чтобы вернуться туда, где это было .. просто предположение, хотя заранее спасибо


Спасибо за вашу помощь в этом.

Чтобы объяснить немного больше, у меня есть экземпляры потоков, записывающие строковую информацию в сокет, который также выводится в файл. Эти потоки запускают свои таймеры, чтобы они самостоятельно записать свои выводы в розетку. Когда программа запускается, я также вижу их вывод на стандартный вывод, но все останавливается, как только я вижу строку отладки из сигнала.

Мне нужны темы, чтобы постоянно посылать эту информацию, но мне нужна основная программа для принять команду, чтобы она также начала делать что-то еще (параллельно) некоторое время. Я думал, что смогу послать сигнал из командной строки, чтобы вызвать это.

Ответы [ 4 ]

2 голосов
/ 29 января 2010

Смешивание сигналов и потоков всегда немного ненадежно. Однако то, что вы описываете, не должно произойти. Python обрабатывает только сигналы в основном потоке. Если ОС доставила сигнал другому потоку, этот поток может быть кратковременно прерван (при выполнении, скажем, системного вызова), но он не будет выполнять обработчик сигнала. Основному потоку будет предложено выполнить обработчик сигнала при следующей возможности.

Что ваши потоки (включая основной поток) на самом деле делают при отправке сигнала? Как вы замечаете, что они все «останавливаются»? Это короткая пауза (легко объясняемая тем, что главному потоку нужно будет получить GIL перед обработкой сигнала), или процесс полностью прерывается?

1 голос
/ 01 февраля 2010

Я вроде как отвечу на свой вопрос: В моей первой попытке я использовал time.sleep (run_time) в основном поток, чтобы контролировать, как долго потоки бежали, пока они не были остановлены. Добавляя отладка я мог видеть, что цикл сна, казалось, завершается, как только обработчик сигнала вернулся, поэтому все было нормально, но рано!

Я заменил сон циклом while, и после обработчик сигнала возвращается, поэтому мои потоки продолжают работать. Так что это решает проблема, но я все еще немного озадачен поведением sleep ().

0 голосов
/ 01 февраля 2010

Смотрите эту презентацию Дэвида Бизли.

http://blip.tv/file/2232410

Также объясняется странное поведение, связанное с потоками и сигналами (специфично для Python, а не общая причудливость темы :-)).

http://pyprocessing.berlios.de/ Pyprocessing - это удобная библиотека, которая упрощает работу с отдельными процессами в Python.

0 голосов
/ 29 января 2010

Вы, вероятно, должны использовать переменную threading.Condition вместо отправки сигналов. Пусть ваш главный поток проверит его каждый цикл и выполнит его специальную операцию, если он установлен.

Если вы настаиваете на использовании сигналов, вам следует перейти к использованию подпроцесса вместо потоков, поскольку ваша проблема, вероятно, связана с GIL.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...