在python中同时读取stdin和写入stdout

在python中同时读取stdin和写入stdout,python,subprocess,Python,Subprocess,我是线程新手,所以我觉得好像我遗漏了一个明显的要点,但我找不到与此主题相关的先前问题 我想制作一个程序,它可以写入标准输入并读取c程序的标准输出。这是主程序中的代码 从子流程导入Popen,管道 从线程导入线程 从队列导入队列,为空 从操作系统导入getcwd 导入时间 随机输入 chatter=队列(maxsize=10)#要发送到程序的字符串队列 类Chatter(): def stream_talker(自身、标识符、流): 尽管如此: 如果不是chatter.empty(): self.

我是线程新手,所以我觉得好像我遗漏了一个明显的要点,但我找不到与此主题相关的先前问题

我想制作一个程序,它可以写入标准输入并读取c程序的标准输出。这是主程序中的代码

从子流程导入Popen,管道
从线程导入线程
从队列导入队列,为空
从操作系统导入getcwd
导入时间
随机输入
chatter=队列(maxsize=10)#要发送到程序的字符串队列
类Chatter():
def stream_talker(自身、标识符、流):
尽管如此:
如果不是chatter.empty():
self.proc.stdin.write(chatter.get(True,1))
def流监视程序(自身、标识符、流):
尽管如此:
对于流中的行:
打印行
def主(自):
self.proc=Popen(getcwd()+'/main',stdout=PIPE,stdin=PIPE)
线程(target=self.stream\u talker,name='stdin-talker',args=('stdin',self.proc.stdin)).start()
线程(target=self.stream\u watcher,name='stdout-listening',args=('stdout',self.proc.stdout)).start()
尽管如此:
chat=原始输入('输入chatter:')
如果len(聊天室)>0:
chatter.put(聊天)
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
chatt=Chatter()
chatt.main()
这是它调用的主.c程序

#包括
#包括
int main(){
而(1){
读取整数字节;
大小单位=100;
char*my_字符串;
my_string=(char*)malloc(n字节+1);
bytes\u read=getline(&my\u string,&nbytes,stdin);
如果(字节数_读取==-1)
{
放置(“错误!”);
}
否则{
放置(我的_字符串);
}
免费(我的_字符串);
}
返回0;
}

当前的问题是,虽然stdout将运行,但它永远不会打印

看起来您的主要问题是调用了两个
stream\u talker()
s和no
stream\u watcher()

此外,您可能不想在队列中忙着等待(因为这违背了使用队列的全部意义)。您的代码以尽可能快的速度轮询chatter.empty(),直到队列中有内容为止。直接使用chatter.get();它会一直阻塞,直到有东西可用或达到您的超时


最后,如果您写入
stream\u talker()
中的
stream
参数,而不是硬编码self.proc.stdin,您可能会避免将来的一些困惑。

是否尝试刷新缓冲区(两端)?1。您可以使用两次
stream\u talker
。您还需要运行
流\u watcher
。2.3.这是@J.F.Sebastian,我现在正在研究这两个答案。谢谢你的链接。还有块缓冲问题和预读错误。谢谢你让我注意到这个明显的stream_talker错误。然而,忽略chatter.empty()会导致引发空异常,我将其放在适当的位置以确保不会发生这种情况。感谢您指出,我也不必硬编码。如果队列仍然为空,则在达到超时(您已指定超时1秒)后引发异常。如果这不是您想要的,只需调用
.get()
,不带参数。@LiamPieri:您可以将
while True
循环替换为:
for line in iter(chatter.get,None):stream.write(line)
@保罗我明白了,谢谢您的澄清,我已经忘记了那个参数的作用。