2017-01-30 4 views
1

Существует родитель и ребенок, они соединены через трубы. Родитель выполняет неблокирующее чтение с дочернего элемента, а также делает запись блокировки на трубке ребенка. Кроме того, я использую select() с таймаутом для чтения без блокировки.Использование каналов для взаимодействия в интерактивном режиме не работает. Я тоже попробовал flush(). Что я делаю не так?

код для родителя:

import os 
import sys 
from time import sleep 
import signal 
import fcntl 
from select import select 
from subprocess import Popen, PIPE 

p = Popen(['python', 'bot2.py'],stdout=PIPE, stdin=PIPE, close_fds=True) 

flg = fcntl.fcntl(p.stdout.fileno(), fcntl.F_GETFL) 
fcntl.fcntl(p.stdout.fileno(), fcntl.F_SETFL, flg | os.O_NONBLOCK) 

for i in range(5): 
    p.stdin.write('hello world {}\n'.format(i)) 
    p.stdin.flush() 
    # sleep(2.0) 
    ready = select([p.stdout.fileno()], [], [], 5.0) 
    if len(ready) == 1: 
     print 'msg from bot: {}'.format(os.read(p.stdout.fileno(), 100)) 
    else: 
     print "The bot did not print anything" 
os.kill(p.pid, signal.SIGTERM) 

код для ребенка (bot2.py)

import os 
import sys 
from time import sleep 
from select import select 

sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0) 
while True: 
    a = raw_input() 
    print a 
    sys.stdout.flush() 

Цель состоит в том чтобы установить связь между процессами, чтобы они могли читать и писать трубы альтернативно. Я думаю, что flush() не выполняет эту работу. Я попытался использовать python -u, чтобы установить размер буфера в ноль. Что я делаю не так?

ответ

1

select() возвращает тройку из списка готовых объектов. Итак, в вашем случае len(ready) всегда возвращает 3. Он должен быть len(ready[0]), если вы пытаетесь читать от ребенка.

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