1

我在这里有一个 java 应用程序,它通过 java.lang.Process API 启动一个 C++ 应用程序,然后尝试通过标准输入管道向它发送命令:

process.getOutputStream().write("foo\n");
process.getOutputStream().flush();

在 C++ 端,有一个循环正在运行,它检查标准输入中的输入,如果有的话,它会读取它。不幸的是,检查总是返回 0,因此它从不尝试读取。如果我删除检查,那么它会突然开始查看命令并处理它们。这是在linux上。

从标准输入检查和读取的 C++ 应用程序代码是这样的:

fd_set fds;
FD_ZERO ( &fds );
FD_SET (0, &fds);

结构时间值电视;
tv.tv_sec = 0;
tv.tv_usec = 0;


if( 选择 ( 1, &fds, 0, 0, &tv ) > 0 ) {
    字符缓冲区[16384];
    buf[16383] = '\0';
    if ( fgets ( buf, sizeof ( buf ) - 1, stdin ) == 0 )
        返回;
}

正如我所说,删除 if 子句使其工作,但当然这不是很好,因为它周围的循环还做了一些其他事情。有人知道我在这里做错了什么吗?

更新:同时,我能够用两个非常小的示例应用程序重现该问题。问题似乎与这里的 Qt 框架有关,只要我创建了框架所需的 QCoreApplication 实例,stdin 的 select() 似乎就不再起作用了。

4

5 回答 5

1

你有两个如果;删除哪一个使它起作用?

fgets()不会在返回之前等待换行符、缓冲区满或 EOF 吗?我没有看到您写换行符,“foo”没有填充缓冲区,并且由于流没有关闭,它是否看到 EOF?

于 2009-06-17T14:49:32.870 回答
0

原来它不是 QCoreApplication,因为我现在可以在没有问题的情况下重现该问题两次。似乎问题是我正在使用的 fgets() ,用 read() 替换它可以修复它。

于 2009-06-17T15:39:55.030 回答
0

我记得有很多关于 select() 的语义和操作以及它的一些替代品的争论。你可能会看那些。

您正在阅读的流是如何创建/打开的?它是缓冲流吗?也许你什么也得不到,因为在写入过程刷新它之前它没有被写入流?

您可能会尝试的另一件事是将其放在具有阻塞 I/O 而不是轮询的线程上。

祝你好运

于 2009-06-17T15:23:58.027 回答
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) 
{ 
}
于 2009-06-17T17:38:43.127 回答
0

I may be wrong, but does having a timeout of 0 for the select call makes sense? I would try to increase the timeout value.

于 2009-06-17T14:40:34.010 回答