简体   繁体   English

我的 C++ 程序如何才能等到对命名的 pipe 进行新的写入?

[英]How can my C++ program wait until a new write has been made to the named pipe?

I have two separate programs in C++, one that writes to two named pipes in unpredictable intervals and one that should wait to read new content from the pipes whenever available.我在 C++ 中有两个单独的程序,一个以不可预知的间隔写入两个命名管道,一个应该等待从管道中读取新内容,只要可用。 For simplicity, here my writer only writes two times to the pipes (1st: "One" "Tree", 2nd: "Two" "Fogs").为简单起见,这里我的作者只写了两次管道(第一次:“One”“Tree”,第二次:“Two”“Fogs”)。

My writer program is:我的作家计划是:

#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);
}   

My reader program is:我的阅读器程序是:

#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;
}

I do not want the reader to terminate or close the connection between the reads, I need it to remain active and wait until the writer writes something new in the named pipe.我不希望读者终止或关闭读取之间的连接,我需要它保持活动状态并等到作者在名为 pipe 中写入新内容。 However, by simultaneously running these two programs (in different cores, first the writer and then the reader) I get:但是,通过同时运行这两个程序(在不同的内核中,首先是编写器,然后是读取器),我得到:

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

The wanted behavior would be:想要的行为是:

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

and then nothing (the reader should wait for another write).然后什么都没有(读者应该等待另一个写入)。

I understand that I should somehow clear the buffer after I read it, but isn't it the default behavior of read?我知道我应该在读取缓冲区后以某种方式清除缓冲区,但这不是读取的默认行为吗? Since it finished reading "Two" (and also "Fogs"), why does it keep reading it and does not wait for new content?既然读完了《二》(还有《迷雾》),为什么还要一直读,不等新内容呢?

What modifications should I make?我应该做哪些修改?

Thank you very much in advance!非常感谢您!

Closing a pipe signals end-of-file to the other end.关闭 pipe 将文件结束信号发送到另一端。

read will read zero bytes (and return zero) whenever it encounters an end-of-file condition.每当遇到文件结束条件时, read将读取零字节(并返回零)。 Any subsequent read after the end-of-file is a no-op.文件结尾之后的任何后续读取都是空操作。

If you want to continue reading from the same pipe, you need to check the result of read , and if it returns zero, close the pipe and open it again.如果要继续从同一个 pipe 读取,则需要检查read的结果,如果返回零,则关闭 pipe 并再次打开它。

Of course you should not unlink the pipe if you need someone else to continue using it.当然,如果您需要其他人继续使用它,则不应unlink pipe 的链接。

One other thing to note: read (1) doesn't terminate the buffer with the 0 byte and (2) doesn't necessarily read the exact amount of bytes that was written by a single write .另一件需要注意的事情: read (1) 不会以 0 字节终止缓冲区,并且 (2) 不一定读取单个write的确切字节数。 You should detect the end-of-message yourself, rather than relying on read and write to do it for you.您应该自己检测消息结束,而不是依靠read write为您完成。 It is entirely possible that read will read a half of the string without the terminating null character, then your printf will print garbage. read 完全有可能在没有终止 null 字符的情况下read字符串的一半,然后您的printf将打印垃圾。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM