2015-02-11 63 views
1

我是线程新手,所以我觉得好像我错过了一个明显的观点,但是我找不到与此主题有关的以前的问题。同时阅读stdin并在python中写入标准输出

我想写一个程序写入stdin并读取一个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; 

} 

目前的问题是,虽然它会运行,但stdout永远不会被打印。

+1

您是否尝试冲洗缓冲区(两端)? – 2015-02-11 17:50:16

+0

1.你使用'stream_talker'两次。你也想运行'stream_watcher'。 2. [你应该强制行缓冲](http://stackoverflow.com/q/20503671/4279)3.它[足以启动一个线程来同时提供输入和读取输出](http: //stackoverflow.com/q/28291847/4279) – jfs 2015-02-11 18:16:49

+0

@JFSebastian我正在寻找这两个答案,现在感谢您的链接。 – 2015-02-11 18:32:48

回答

3

它看起来像你的主要问题是,你调用两个stream_talker() s和没有stream_watcher()

此外,你可能不想忙于等待你的队列(因为这违背了使用队列的全部观点)。您的代码尽可能快地轮询chatter.empty(),直到队列中有内容为止。直接使用chatter.get();它会阻塞,直到有可用或直到它超时。

最后,如果您在stream_talker()中写入stream参数,而不是硬编码self.proc.stdin,则可能会为自己节省一些未来的混淆。

+0

还有块缓冲问题和预读错误 – jfs 2015-02-11 18:21:17

+0

谢谢你给我留下了这个明显的stream_talker错误。然而,省略chatter.empty()会产生空的异常,我把它放在适当的位置以确保不会发生。感谢您指出我不必对其进行硬编码。 – 2015-02-11 18:27:58

+1

如果队列仍然为空,则在超时命中(您已指定超时1秒)后引发异常。如果这不是你想要的,只需调用不带参数的'.get()'。 – 2015-02-11 18:35:54

相关问题