Linux 之 FIFO
正文
FIFO 也被称为命名管道,相较于pipe来说,FIFO可以在非亲缘进程间通信。
FIFO也是由内核维护的队列,虽然有文件路径,但是不属于文件系统中。
函数原型:
#include <sys/types.h>
#include <sys/stat.h>
int mkfifo(const char *filename, mode_t mode);
使用 mkfifo 创建FIFO文件,filename为文件的路径,mode为文件权限,在这里要注意掩码对于创建文件权限的影响。创建失败返回-1,如果FIFO文件已存在,errno值为EEXIST。
父写子读
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<fcntl.h>
#include<errno.h>
int main()
{
umask(0);
if(mkfifo("./fifo",0666) == -1)
{
if(errno != EEXIST)
{
perror("文件创建失败");
exit(-1);
}
}
pid_t id = fork();
if(id == -1)
{
perror("进程创建失败");
exit(-1);
}
else if(id == 0) //子进程
{
int fd_read = open("./fifo",O_RDONLY);
if(fd_read == -1)
{
perror("子进程FIFO打开失败");
exit(-1);
}
char buf[100];
memset(buf,0,sizeof(buf));
int re = read(fd_read,buf,sizeof(buf));
if(re != -1)
printf("子进程读取成功: %s\n",buf);
else
{
printf("子进程读取失败\n");
exit(-1);
}
}
else //父进程
{
int fd_write = open("./fifo",O_WRONLY);
if(fd_write == -1)
{
perror("父进程FIFO打开失败");
exit(-1);
}
int re = write(fd_write,"hello world",12);
if(re != -1)
printf("父进程写入成功\n");
else
{
printf("父进程写入失败\n");
exit(-1);
}
}
}
在父进程以只写的方式打开,子进程以只读的方式打开。
FIFO的打开
FIFO文件在没有满足读写都打开的情况下,只打开一端会阻塞住。
例如,只以O_RDONLY方式打开,会阻塞直到有以O_WRONLY方式打开,反之亦然。