Python вызывает pipe.communicate () в потоке - PullRequest
3 голосов
/ 30 марта 2010

При использовании Python 2.6.1 в Mac OS X 10.6.2 возникает следующая проблема:

У меня есть многопоточный процесс (класс Thread), и у каждого из этих потоков есть канал (подпроцесс. Открыто), что-то любит:

 from threading import Thread

 cmd = "some_cmd"

 class Worker(Thread):
    def run(self):
       pipe = Popen(cmd,
        stdin=PIPE,
        stdout=PIPE,
        stderr=PIPE)

       out, err = pipe.communicate("some data")

Проблема в том, что код pipe.communicate () блокируется. Интересно, что когда я отправлял прерывание (например, Ctrl-C KeyboardInterrupt) родительскому процессу, он разблокируется.

Интересно, что когда я использую class Worker(multiprocessing.Process), код работает просто отлично.

Любые мысли о том, почему это блокирует - и как это исправить - , будут с благодарностью.

Спасибо.

Ответы [ 2 ]

1 голос
/ 30 марта 2010

Если вы вызовете sys.exit() в главном потоке, другие потоки будут прерваны при следующей возможности (в большинстве операционных систем). Однако, если они находятся в блокирующем вызове (например, Communication ()), они будут ждать, пока блокирующий вызов не завершится, прежде чем завершить. Control-C работает, потому что заставляет операционную систему прерывать блокирующий вызов.

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

В вашем конкретном случае вы можете сохранить объекты Popen в глобальном set() перед вызовом сообщения и иметь вызов основного потока Popen.terminate() для каждого из них непосредственно перед выходом. Это приведет к выходу дочернего элемента, возврату communicate() и выходу потока.

Вы устанавливаете поток как демон поток?

1 голос
/ 30 марта 2010

Использование нескольких потоков и нескольких процессов часто вызывает проблемы, особенно (хотя и не исключительно) в системах на основе Unix; Я рекомендую вам просто избегать смешивания двух.

...