我这里有一个java应用程序,它通过java.lang.Process API启动一个C ++应用程序,然后尝试通过stdin管道向它发送命令:
process.getOutputStream().write("foo\n"); process.getOutputStream().flush();
在C ++方面,有一个循环运行,它检查stdin中的输入,如果有的话 它读了它。不幸的是,检查总是返回0,因此它永远不会尝试读取。如果我删除了支票,那么它会突然开始看到命令并处理它们。这是在Linux上。
要检查和读取stdin的C ++应用程序代码是:
fd_set fds; FD_ZERO ( &fds ); FD_SET ( 0, &fds ); struct timeval tv; tv.tv_sec = 0; tv.tv_usec = 0; if( select ( 1, &fds, 0, 0, &tv ) > 0 ) { char buf[16384]; buf[16383] = '\0'; if ( fgets ( buf, sizeof ( buf ) - 1, stdin ) == 0 ) return; }
正如我所说,删除if子句会使它工作,但当然这不太好,因为它周围的循环也做了一些其他事情。有谁知道我在这里做错了什么?
更新: 同时我能用两个非常小的示例应用程序重现问题。这个问题似乎与Qt框架有关,一旦我创建了框架所需的QCoreApplication实例,那么stdin的select()似乎不再起作用了。
答案 0 :(得分:1)
你有两个if;删除哪一个使它工作?
fgets()在返回之前是否等待换行符,缓冲区已满或EOF?我没有看到你写一个换行符,“foo”没有填充缓冲区,并且由于流没有关闭,它是否看到了EOF?
答案 1 :(得分:0)
我可能错了,但select
通话的超时时间是否合理?我会尝试增加超时值。
答案 2 :(得分:0)
我记得有很多关于select()的语义和操作以及它的几个替换的争论。你可以看看那些。
您正在阅读的流如何创建/打开?它是缓冲流吗?也许你什么也得不到,因为在写入过程冲刷之前它还没有被写入流中?
你可能尝试的另一件事是将它放在一个阻塞I / O而不是轮询的线程上。
祝你好运
答案 3 :(得分:0)
原来它不是QCoreApplication,因为我现在可以用out重现问题两次。似乎问题是我正在使用的fgets(),用read()替换它会修复它。
答案 4 :(得分:0)
下面是while循环吗?如果没有,那应该是。
FD_ZERO ( &fds );
FD_SET ( 0, &fds );
struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = 0;
如果我的第一个问题的答案是肯定的,那么请尝试此超时:
tv.tv_sec = 0;
tv.tv_usec = 1;
如果上述方法不起作用,请尝试以下方法:
while(fgets(buf, sizeof ( buf ) - 1, stdin) !=NULL)
{
}