Попытка записи и чтения из каналов в подпроцесс сложна из-за буферизации по умолчанию, выполняемой в обоих направлениях.Очень легко получить тупик, когда один или другой процесс (родительский или дочерний) читает из пустого буфера, записывает в полный буфер или выполняет блокирующее чтение в буфере, который ожидает данные, прежде чем системные библиотеки очистят его.
Для более скромных объемов данных может быть достаточно метода Popen.communicate()
.Тем не менее, для данных, которые превышают его буферизацию, вы, вероятно, остановитесь на процессах (похоже на то, что вы уже видите?)
Возможно, вы захотите узнать подробности об использовании модуля fcntl
и создании одного илидругой (или оба) из ваших файловых дескрипторов неблокируемый.В этом случае, конечно, вам нужно будет обернуть все операции чтения и / или записи в эти файловые дескрипторы в соответствующую обработку исключений для обработки событий «EWOULDBLOCK».(Я не помню точное исключение Python, которое выдается для них).
Совершенно другой подход заключается в том, чтобы ваш родитель использовал модуль select
и os.fork()
... и для дочернего процессаexecve()
целевой программе после непосредственной обработки любого файла dup ().(По сути, вы бы заново реализовали части Popen()
, но с другой обработкой дескриптора родительского файла (PIPE).
Кстати, .communicate, по крайней мере в стандартных библиотеках Python 2.5 и 2.6, будет обрабатывать только около64 КБ удаленных данных (в Linux и FreeBSD). Это число может варьироваться в зависимости от различных факторов (возможно, включая параметры сборки, используемые для компиляции вашего интерпретатора Python, или версию libc, с которой он связан). Оно НЕ просто ограничено доступнымпамять (несмотря на утверждение Дж.Ф. Себастьяна об обратном), но ограничена гораздо меньшим значением.