简体   繁体   中英

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 . startloop creates a fifo and continually writes to it with each read of the client ( 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:

#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":

hostname:dir username$ ./readbyte fifo 
65

As I expect, loopstart doesn't print anything until I read from the fifo with readbyte . However, when it becomes unblocked, it writes to "fifo" several times instead of immediately being suspended. 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. 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).

As to why the first write appears to block - it actually doesn't. It is the open that blocks. From the fifo manaul :

The FIFO must be opened on both ends (reading and writing) before data can be passed. Normally, opening the FIFO blocks until the other end is opened also.

Update: Actually the above is true for the first write . But there is probably more to explanation. Once the readbyte program closes the fifo, subsequent write calls should start failing.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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