简体   繁体   English

为什么没人读后继续写入命名管道?

[英]Why does writing to a named pipe continue after no one is reading?

I'm doing some experiments to learn about named pipes. 我正在做一些实验来了解命名管道。 It's my understanding that the OS will block a program that writes to a named pipe until another program reads from the named pipe. 据我了解,操作系统将阻止写入命名管道的程序,直到另一个程序从命名管道读取数据。 So I've written two programs, startloop and readbyte . 所以我写了两个程序, startloopreadbyte startloop creates a fifo and continually writes to it with each read of the client ( readbyte ): startloop创建一个fifo,并在每次读取客户端( readbyte )时不断对其进行写操作:

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

int main(int argc, char *argv[]) {
    const char num = 123;
    mkfifo("fifo", S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
    int fd = open("fifo", O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
    while (1) {
        printf("loop_start\n");
        write(fd, &num, sizeof(num));
    }
    close(fd);
    return 0;
}

readbyte reads one byte from the fifo when run: readbyte在运行时从fifo读取一个字节:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>

int main(int argc, char *argv[]) {
    char num;
    int fd;
    if ((fd = open(argv[1], O_RDONLY, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) == -1) {
        perror("Cannot open input file\n"); exit(1);
    }

    read(fd, &num, sizeof(num));
    printf("%d\n", num);
    close(fd);
    return 0;
}

readbyte prints the number as expected when run on "fifo": readbyte在“ fifo”上运行时按预期打印数字:

hostname:dir username$ ./readbyte fifo 
65

As I expect, loopstart doesn't print anything until I read from the fifo with readbyte . 如我所料, loopstart不会打印任何内容,直到我从带有readbyte读取它readbyte However, when it becomes unblocked, it writes to "fifo" several times instead of immediately being suspended. 但是,当它被解除阻塞时,它多次写入“ fifo”,而不是立即被挂起。 Why is this? 为什么是这样?

hostname:dir username$ ./startloop
loop_start
loop_start
loop_start
loop_start
loop_start
loop_start
loop_start
loop_start
loop_start
loop_start
loop_start
loop_start
loop_start
loop_start
loop_start
loop_start
loop_start
loop_start
loop_start
loop_start

"It's my understanding that the OS will block a program that writes to a named pipe until another program reads from the named pipe." “据我了解,操作系统将阻止写入命名管道的程序,直到另一个程序从命名管道读取数据。”

That understanding is incorrect. 这种理解是不正确的。 write will not block unless the pipe/fifo is full. 除非管道/ FIFO已满,否则write将不会阻塞。 From the pipe manul : 管道操作

A pipe has a limited capacity. 管道的容量有限。 If the pipe is full, then a write(2) will block or fail, depending on whether the O_NONBLOCK flag is set (see below). 如果管道已满,则取决于是否设置了O_NONBLOCK标志(请参见下文),write(2)将阻塞或失败。

As to why the first write appears to block - it actually doesn't. 至于为什么第一次write似乎被阻止-实际上却没有。 It is the open that blocks. open是阻碍。 From the fifo manaul : fifo手册

The FIFO must be opened on both ends (reading and writing) before data can be passed. 必须先在两端打开FIFO(读取和写入),然后才能传递数据。 Normally, opening the FIFO blocks until the other end is opened also. 通常,打开FIFO块,直到另一端也打开。

Update: Actually the above is true for the first write . 更新:实际上,以上对于第一次write都是正确的。 But there is probably more to explanation. 但是可能还有更多的解释。 Once the readbyte program closes the fifo, subsequent write calls should start failing. 一旦readbyte程序关闭了fifo,随后的write调用应开始失败。

test the write result 测试写入结果

 while (1) {
        printf("loop_start\n");
     int ret =  write(fd, &num, sizeof(num));
     if(ret == -1)
     {
        perror("error writing to fifo");
        exit(1);
     }
    }

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

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