我正在做一些实验来了解命名管道。根据我的理解,操作系统将阻止写入命名管道的程序,直到另一个程序从命名管道读取为止。所以我写了两个程序startloop
和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
在运行时读取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
在&#34; fifo&#34;
hostname:dir username$ ./readbyte fifo
65
正如我所料,loopstart
在我使用readbyte
读取fifo之前不会打印任何内容。然而,当它被解锁时,它会写入&#34; fifo&#34;几次而不是立即被停职。这是为什么?
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
答案 0 :(得分:3)
“我的理解是操作系统将阻止写入命名管道的程序,直到另一个程序从命名管道读取。”
这种理解是不正确的。除非管道/ fifo已满,否则write
不会阻止。来自pipe manul:
管道容量有限。如果管道已满,则写入(2) 将阻塞或失败,具体取决于是否设置了O_NONBLOCK标志 (见下文)。
至于为什么第一个write
似乎阻止了 - 实际上并没有。是open
阻止。来自fifo manaul:
必须在数据之前打开FIFO(读取和写入) 可以通过。通常,打开FIFO块直到另一端 也开了。
更新:实际上上面的第一个write
是正确的。但可能有更多的解释。一旦readbyte
程序关闭了fifo,后续的write
调用应该开始失败。
答案 1 :(得分:1)
测试写入结果
while (1) {
printf("loop_start\n");
int ret = write(fd, &num, sizeof(num));
if(ret == -1)
{
perror("error writing to fifo");
exit(1);
}
}