2010-07-16 2 views
1

Я пытаюсь выполнить два процесса связи с использованием трубы. Я сделал это в родительском процессе:создание программ python «чат» по трубе

process = subprocess.Popen(test, shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE) 

process.stdin.write("4\n"); 
output = process.stdout.read() 
print output 

и в дочернем процессе:

inp = raw_input() 
integer = int(inp) 
print integer**2 
while(True): 
    pass 

Я бы ожидать, что родительский процесс для печати 16 ... К сожалению, она остается висеть без печати ничего. Замена бесконечного цикла на спящий режим в течение 5 секунд делает родительский процесс бездействующим в течение 5 секунд и ПОСЛЕ того, что печатает 16. Это показывает, что родительский процесс получает только результат от дочернего элемента после его завершения.

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

Любая помощь? Спасибо,

Manuel

+3

вы пробовали промывку потока, когда вы пишете '«4 \ п» '? –

+0

Да, это не проблема. Дочерний процесс фактически получает это 4, и я видел его, потому что после прочтения этого ввода я пишу его в обычный файл и затем вводим бесконечный цикл. Родительский процесс - это тот, который блокируется в части read(). –

+0

Из любопытства, почему вы не использовали 'sys.stdin.readline()' в дочернем процессе? –

ответ

2

Как было предложено ndim, сделать на следующий в родительском:

process.stdin.write("4\n")  
process.stdin.flush()  
output = process.stdout.readline()  
print output 

Вам также необходимо изменить ребенок:

inp = sys.stdin.readline() 
integer = int(inp) 
sys.stdout.write("%d\n", (integer ** 2,)) 
sys.stdout.flush() 

Я использовал sys.stdin.readline и sys.stdout.write как вопрос стиля.

я написал 2 test programs и они прекрасно работали с питоном-2.6.4-27 на Fedora 13.

+0

это не проблема, но спасибо за помощь и советы по стилю! –

+0

@Manuel: Вы пробовали новые программы? –

+0

Я решил это, но ОЧЕНЬ уродливо. Ваше решение прост и очень чист! Большое спасибо. (вы получаете знак решения, потому что я обновляю свой код до этого ...) –

4

Я вижу несколько возможных вопросов:

а) процесс ребенок никогда не переполняется выход и, таким образом, фактически никогда не посылает свой выход к родителю.

b) Родительский процесс запускает свой вызов read() до того, как дочерний процесс фактически отправил свой вывод (сбросил его вывод).

c) Родительский процесс блокирует read(), который до тех пор, пока EOF, который эффективно означает, что он ждет выхода ребенка. В документах subprocess.Popen следует указать, может ли это быть так.

d) Звонок read() родительского процесса ожидает определенного количества байтов (например, 1024), чтобы прибыть до его возвращения.

Возможно, что у родителя есть много read(1) звонков и повторная сборка байтов по мере их поступления исправят проблему. Или с использованием API связи более высокого уровня, например. используя дейтаграммы вместо синтаксического анализа байтовых потоков.

0

Вы должны использовать для этого выбор. Как и в методе связи подпроцесса. Об этом в python issue tracker.

Смежные вопросы