Буферизация в дочерних процессах является распространенной проблемой. Вот четыре возможных подхода.
Во-первых, проще всего, вы можете читать по одному байту за раз из вашего канала. Это то, что я бы назвал «грязным хаком», и он несет в себе снижение производительности, но это легко, и он гарантирует, что ваши вызовы read () будут блокироваться только до появления первого байта, а не ждать, пока буфер заполнится. никогда не заполнится. Однако это не заставляет другой процесс очищать свой буфер записи, поэтому, если это проблема, этот подход вам все равно не поможет.
Во-вторых, и я думаю, что в следующем, простейшем случае, рассмотрите возможность использования Twisted Framework, в котором есть средство для использования виртуального терминала, или pty (я думаю, «псевдо-телетайп») для общения с вашим дочерним процессом. Тем не менее, это может повлиять на дизайн вашего приложения (возможно, в лучшую сторону, но это может не быть в карточках для вас независимо от). http://twistedmatrix.com/documents/current/core/howto/process.html
Если ни один из вышеперечисленных вариантов не подходит для вас, вы сами решаете сложные проблемы параллелизма ввода-вывода.
В-третьих, попробуйте установить ваши каналы (все они, перед fork ()) в неблокирующий режим, используя fcntl () с O_NONBLOCK. Затем вы можете использовать select () для проверки готовности к чтению / записи, прежде чем пытаться читать / писать; но вы все равно должны поймать IOError и проверить EAGAIN, потому что это может произойти даже в этом случае. Это может, в зависимости от поведения дочернего процесса, позволить вам подождать, пока данные действительно появятся, прежде чем пытаться их прочитать.
Последнее средство - реализовать логику PTY самостоятельно. Если вы видели ссылки на такие вещи, как опции termio, вызовы ioctl () и т. Д., То вы против этого. Я не делал этого раньше, потому что это сложно, и я никогда не нуждался в этом. Если это твоя судьба, удачи.