FIFO简介:
FIFO,即命名管道, 也是Linux系统的一种进程间通信方式,不同于匿名管道,命名管道可以进行“非父/子关系”进程间通信,而且以文件节点的形式在。使用mkfiifo可以创建这个文件节点文件。
First In First Out的缩写,意为先进先出,正好是命令管道的特点。
命名管道是一个特殊的文件节点:
要使用FIFO,先创建fifo文件,读端通过read来从fifo读取(类似于文件读取);写端通过read来从fifo读取(类似于文件写入)。
下面是一个命名管道文件:
fifo1.lnk
fifo1.lnk就是创建的管道,可见,后缀是lnk文件。命名管道以一种特殊的文件形式存在,在提供管道功能的同时,也具有了普通文件的优点(可以同时被多个进程夹享)。
mkfifo函数声明:
#include <sys/types.h>
#include <sys/stat.h>
int mkfifo( const char* pathname, mode_t mode );
功能:创建命名管道,即“在文件系统中创建一个文件,该文件用于提供FIFO功能”。
参数:
第一个参数(pathname)是将要在文件系统中创建的一个专用文件;
第二个参数(mode)用来规定FIFO的读写权限。
返回值:
如果调用成功的话,返回值为0;
如果调用失败返回值为-1。
FIFO使用举例:
下面我们以一个实例来说明如何使用mkfifo函数建一个FIFO,以及进行FIFO的读写。
实现两个c文件,分别进行读和写,在读端进行FIFO文件节点的创建,并读取数据;在写端把数据写入FIFO文件节点。
read_fifo.c(读端):
#include<stdio.h>
#include<stdlib.h>
#include<errno.h>
#include<fcntl.h>
#include<sys/stat.h>
/* 读 */
int main()
{
int fd;
int len;
char buf[1024];
if(mkfifo("fifo1", 0666) < 0 && errno!=EEXIST) // 创建FIFO管道
perror("Create FIFO Failed");
if((fd = open("fifo1", O_RDONLY)) < 0) // 以读打开FIFO
{
perror("Open FIFO Failed");
exit(1);
}
while((len = read(fd, buf, 1024)) > 0) // 读取FIFO管道
printf("Read message: %s", buf);
close(fd); // 关闭FIFO文件
return 0;
}
读端调用mkfifo和read。fifo1就是创建的管道。
write_fifo.c(写端):
#include<stdio.h>
#include<stdlib.h> // exit
#include<fcntl.h> // O_WRONLY
#include<sys/stat.h>
#include<time.h> // time
int main()
{
int fd;
int n, i;
char buf[1024];
time_t tp;
printf("I am %d process.\n", getpid()); // 说明进程ID
if((fd = open("fifo1", O_WRONLY)) < 0) // 以写打开一个FIFO
{
perror("Open FIFO Failed");
exit(1);
}
for(i=0; i<10; ++i)
{
time(&tp); // 取系统当前时间
n=sprintf(buf,"Process %d's time is %s",getpid(),ctime(&tp));
printf("Send message: %s", buf); // 打印
if(write(fd, buf, n+1) < 0) // 写入到FIFO中
{
perror("Write FIFO Failed");
close(fd);
exit(1);
}
sleep(1); // 休眠1秒
}
close(fd); // 关闭FIFO文件
return 0;
}
写端调用open和write。
编译和运行:
分别用gcc编译,得到两个可执行程序:一个read ,一个write,分别用于读写。
read的运行结果:
Read message: Process 3372's time is Thu July 15 07:35:08 2010
Read message: Process 3372's time is Thu July 15 07:35:09 2010
Read message: Process 3372's time is Thu July 15 07:35:10 2010
Read message: Process 3372's time is Thu July 15 07:35:11 2010
Read message: Process 3372's time is Thu July 15 07:35:12 2010
write的运行结果:
I am 3372 process.
Send message: Process 3372's time is Thu July 15 07:35:08 2010
Send message: Process 3372's time is Thu July 15 07:35:09 2010
Send message: Process 3372's time is Thu July 15 07:35:10 2010
Send message: Process 3372's time is Thu July 15 07:35:11 2010
Send message: Process 3372's time is Thu July 15 07:35:12 2010
可见,在read中,创建管道,并且读取数据; 在write中,向管道写入数据。