Reputation: 1069
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
Upvotes: 2
Views: 3406
Reputation: 14044
"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.
Upvotes: 6
Reputation: 50210
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);
}
}
Upvotes: 1