我对两个程序的交互有疑问:
程序 I 必须定期检查是否有来自程序 II 的数据。这应该是非阻塞的。
程序 II 可以在多个实例中运行,因此是并行的。它向程序 I 发送一些数据,然后退出。数据的确切顺序并不那么重要,如果在另一组数据之后 1 秒发送的数据也在 ~1 秒后接收到就足够了。
我的第一个方法是使用 FIFO: “服务器”
int main()
{
int fd;
unlink("/tmp/ctl_fifo");
if (mkfifo("/tmp/ctl_fifo", 0666) == -1)
{
printf("Error creating FIFO\n");
}
while (true)
{
if ((fd = open("/tmp/ctl_fifo", O_RDONLY | O_NONBLOCK)) < 0)
{
printf("Error opening FIFO\n");
}
struct timeval timeout;
timeout.tv_sec = 0;
timeout.tv_usec = 2000;
fd_set set;
FD_ZERO(&set);
FD_SET(fd, &set);
select(fd + 1, &set, NULL, NULL, &timeout);
if (FD_ISSET(fd, &set))
{
char buf[20];
int r = read(fd,buf, sizeof(buf));
printf("%s\n", buf);
}
sleep(1);
}
return 0;
}
“客户”
int main()
{
while (true)
{
int fd;
fd = open("/tmp/ctl_fifo", O_WRONLY);
if (fd < 0)
{
printf("Error opening fifo\n");
}
char buf[] = "Blablubb";
write(fd, buf, sizeof(buf));
sleep(0.1);
}
return 0;
}
问题在于数据可能会被打乱。输出看起来像这样:
Blablubb
ablubb
ubb
b
Blablubb
...
我的问题是:我做错了什么?有没有办法确保数据不会被扰乱?还是有一种完全不同的方法来处理这个问题?
最佳答案
首先,你的资源泄露严重;每次你的循环运行时,你都打开
一个新的流,在那个循环迭代结束时,流泄漏,漂浮在稀薄的空气中,就好像它从未存在过一样......问题是它确实存在存在,而您没有关闭
它。
其次,当您使用 O_NONBLOCK
打开流时,您不需要使用 select
。
read
将在没有任何内容可读时立即返回(错误值),并且使用 O_NONBLOCK
打开流。
int r = read(fd,buf, sizeof(buf));
printf("%s\n", buf);
read
返回一个 ssize_t
(与 size_t
等效的签名)。所以 int r
应该是 ssize_t r
。
继续(从上一段)到 printf
...
printf("%s\n", buf); // THIS IS WRONG!
首先,您需要检查 r
。完全有可能没有收到任何字节,buf
包含纯粹的垃圾。也有可能合并两个写入(并且您最终只打印其中一个)。
为简单起见,我建议您一次接收(并打印)一个字节,接收'\0'
时除外;打印 '\n
' 而不是 '\0'
。像这样:
int fd = open("/tmp/ctl_fifo", O_RDONLY | O_NONBLOCK);
if (fd < 0)
{
printf("Error opening FIFO\n");
}
for (;;)
{
unsigned char c;
ssize_t r = read(fd, &c, 1);
if (r < 0 && errno == EAGAIN) {
/* read sets EAGAIN when no data is available on otherwise valid
* non-blocking streams, and returns -1... so we continue looping
* when that happens */
continue;
}
if (r <= 0) {
/* Any value less than zero without errno == EAGAIN should terminate
* ... and r == 0 means EOF */
break;
}
putchar(c == '\0' ? '\n' : c);
}
close(fd);
关于c - 非阻塞并行 FIFO,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31183404/