我的 C++ 程序如何等到对命名管道进行新写入?

问题描述

我有两个独立的 C++ 程序,一个以不可预测的时间间隔写入两个命名管道,另一个应该等待从管道中读取新内容。为简单起见,我的作者在这里只向管道写入两次(第一次:“一”“树”,第二次:“两个”“雾”)。

我的作家程序是:

#include <unistd.h>
#include <iostream>

int main()
{
    int fd1,fd2;
    const char* myfifo1 = "/tmp/myfifo1";
    const char* myfifo2 = "/tmp/myfifo2";

    mkfifo(myfifo1,0666);
    mkfifo(myfifo2,0666);

    fd1 = open(myfifo1,O_WRONLY);
    fd2 = open(myfifo2,O_WRONLY);

    write(fd1,"One",sizeof("One"));
    write(fd2,"Tree",sizeof("Tree"));

    sleep(5);

    write(fd1,"Two",sizeof("Two"));
    write(fd2,"Fogs",sizeof("Fogs"));

    close(fd1);
    close(fd2);

    unlink(myfifo1);
    unlink(myfifo2);
}   

我的阅读器程序是:

#include <fcntl.h>
#include <stdio.h>
#include <sys/stat.h>
#include <unistd.h>

#define MAX_BUF 1024

int main()
{
    int fd1,fd2;
    const char * myfifo1 = "/tmp/myfifo1";
    const char * myfifo2 = "/tmp/myfifo2";
    char buf1[MAX_BUF],buf2[MAX_BUF];
    
    fd1 = open(myfifo1,O_RDONLY);
    fd2 = open(myfifo2,O_RDONLY);
    
    while (1) {
        read(fd1,buf1,MAX_BUF);
        read(fd2,buf2,MAX_BUF);
        
        printf("Received: %s\n",buf1);
        printf("Received: %s\n",buf2);
    }

    close(fd1);
    close(fd2);
    return 0;
}

我不希望读取器终止或关闭读取之间的连接,我需要它保持活动状态并等待写入器在命名管道中写入新内容。 但是,通过同时运行这两个程序(在不同的内核中,首先是写入器,然后是读取器),我得到:

Received: One
Received: Tree
Received: Two
Received: Fogs
Received: Two
Received: Fogs
Received: Two
Received: Fogs
Received: Two
Received: Fogs
      ...
      ...

想要的行为是:

Received: One
Received: Tree
Received: Two
Received: Fogs

然后什么都没有(读者应该等待另一个写入)。

我知道我应该在读取后以某种方式清除缓冲区,但这不是读取的认行为吗?既然读完了《二》(还有《迷雾》),为什么还要继续读,不等新内容

我应该做哪些修改

在此先非常感谢您!

解决方法

关闭管道向另一端发出文件结束信号。

read 将在遇到文件结束条件时读取零字节(并返回零)。文件结束后的任何后续读取都是空操作。

如果想继续从同一个管道读取,需要检查read的结果,如果返回零,关闭管道再打开。

当然,如果您需要其他人继续使用管道,则不应unlink

要注意的另一件事:read (1) 不会以 0 字节终止缓冲区,并且 (2) 不一定读取单个 {{1} 写入的确切字节数}}。您应该自己检测消息的结尾,而不是依赖 writeread 来为您检测。完全有可能 write 会读取没有终止空字符的字符串的一半,然后您的 read 将打印垃圾。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...