2015-02-11 3 views
1

Я новичок в нарезке, поэтому чувствую, что мне не хватает очевидного момента, но я не мог найти предыдущий вопрос, относящийся к этой теме.Одновременно чтение stdin и запись в stdout в python

Я хочу сделать программу, которая пишет в stdin и читает stdout программы c. Это код в основной программе.

from subprocess import Popen, PIPE 
from threading import Thread 
from Queue import Queue, Empty 
from os import getcwd 
import time 
import random 

chatter = Queue(maxsize=10) # Queue of strings to be sent to the program 


class Chatter(): 
    def stream_talker(self, identifier, stream): 
     while True: 
      if not chatter.empty(): 
       self.proc.stdin.write(chatter.get(True, 1)) 

    def stream_watcher(self, identifier, stream): 
     while True: 
      for line in stream: 
       print line 

    def main(self): 
     self.proc = Popen(getcwd() + '/main', stdout=PIPE, stdin=PIPE) 
     Thread(target=self.stream_talker, name='stdin-talker', args=('STDIN', self.proc.stdin)).start() 
     Thread(target=self.stream_watcher, name='stdout-listening', args=('STDOUT', self.proc.stdout)).start() 

     while True: 
      chat = raw_input('Enter chatter: ') 
      if len(chat) > 0: 
       chatter.put(chat) 


if __name__ == '__main__': 
    chatt = Chatter() 
    chatt.main() 

И вот программа main.c, которую она вызывает.

#include <stdio.h> 
#include <stdlib.h> 

int main(){ 
    while (1){ 
    int bytes_read; 
    size_t nbytes = 100; 
    char *my_string; 

    my_string = (char *)malloc(nbytes + 1); 
    bytes_read = getline (&my_string, &nbytes, stdin); 

    if (bytes_read == -1) 
    { 
     puts ("ERROR!"); 
    } 
    else{ 
     puts (my_string); 
    } 
    free(my_string); 
    } 

    return 0; 

} 

Текущая проблема заключается в том, что, хотя она будет работать, стандартный вывод никогда не печатается.

+1

Вы пытались промыть буферы (с обоих концов)? –

+0

1. Вы используете 'stream_talker' дважды. Вы также хотите запустить 'stream_watcher'. 2. [Вы должны принудительно настроить буферизацию строки] (http://stackoverflow.com/q/20503671/4279) 3. Это [достаточно, чтобы запустить один поток для одновременного ввода и чтения вывода) (http: //stackoverflow.com/q/28291847/4279) – jfs

+0

@JFSebastian Я изучаю оба этих ответа, теперь спасибо за ссылки. –

ответ

3

Похоже, ваша основная проблема заключается в том, что вы вызываете два stream_talker() с и не stream_watcher().

Кроме того, вы, вероятно, не хотите ждать в очереди на очереди (потому что это бросает вызов всей точке использования очереди). Ваш код проверяет chatter.empty() так быстро, как может, пока в очереди ничего нет. Вместо этого используйте chatter.get(); он блокируется до тех пор, пока что-то не будет доступно или пока он не достигнет вашего таймаута.

Наконец, вы можете сэкономить себе некоторую путаницу в будущем, если вы напишете аргумент stream в stream_talker(), а не hardcode self.proc.stdin.

+0

есть также проблема с блочной буферизацией и ошибка чтения с ошибкой – jfs

+0

Благодарим вас за то, что вы заметили ошибку stream_talker. Однако исключение chatter.empty() приводит к тому, что порожденное исключение возникает, я поставил это на место, чтобы убедиться, что этого не произойдет. Спасибо, что указали, что мне тоже не нужно его жестко кодировать. –

+1

Исключение возникает после того, как таймаут ударил (вы указали тайм-аут в 1 секунду), если очередь все еще пуста. Если это не то, что вы хотите, просто вызовите '.get()' без параметров. –

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