1.FIFO的概念
FIFO又称为有名管道,是一种文件类型,在文件系统中可以看到。程序中可以查看文件stat结构中st_mode成员的值来判断文件是否是FIFO文件,创建一个FIFO文件类似于创建文件。FIFO文件就像普通文件一样。
FIFO的通信方式类似于在进程中使用文件来传输数据,只不过FIFO类型文件同时具有管道的特性。在数据读出时,FIFO管道中同时清除数据。在shell中mkfifo命令可以建立有名管道。
用法:mkfifo [options] name
mkfifo -m 666 fifo1 (-m mode 指定了要创建的FIFO的模式,666指定了只有读写权限,FIFO文件隐性的规定不具有执行权限)
2.创建FIFO
FIFO文件像普通文件一样,也可以经过路径名来访问。
#include
#include
int mkfifo(const char *filename,mode_t mode);
参数:mode指定FIFO的读写权限,新创建的FIFO的用户ID和组ID规则与open函数相同。
filename指定新创建FIFO的文件名称。
返回值:如果成功,返回0;出错返回-1,并更改errno的值。
3.FIFO的读写操作
FIFO的写操作规则类似于匿名管道的写操作规则,当没有进程为读打开FIFO,调用write函数来进行写操作会产生信号SIGPIPE,则信号可以被捕捉或被忽略。
注:当FIFO的所有写进程都已关闭,则为FIFO的读进程产生一个文件结束符。
FIFO的出现,解决了系统在应用过程中产生的大量的中间临时文件的问题。FIFO可以被shell调用使数据从一个进程到另一个进程,系统不必为该中间通道去清除不必要的垃圾,或者去释放该通道的资源,它可以被留作后来的进程使用,并且规避了匿名管道在作用于的限制,可应用于不相关的进程之间。
write_fifo.c
- #include <unistd.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <fcntl.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <errno.h>
- #include <limits.h>
- #define BUFS PIPE_BUF //PIPE_BUF管道默认一次性读写的数据长度
- int main(void)
- {
- int fd;
- int n,i;
- char buf[BUFS];
-
- time_t tp;
-
- printf("I am %d\n",getpid());
-
- if((fd=open("fifo1",O_WRONLY))<0) //只写打开FIFO1
- {
- perror("open");
- exit(1);
- }
-
- for(i=0;i<10;i++)
- {
- time(&tp);
- n=sprintf(buf,"write_info %d sends %s",getpid(),ctime(&tp));
- printf("send msg:%s\n",buf);
-
- if(write(fd,buf,n+1)<0){//写入到FIFO中
- perror("write");
- close(fd); //写入FIFO失败,则关闭fifo文件
- exit(1);
- }
- sleep(3); //进程睡眠3秒
- }
-
- close(fd);
- exit(0);
- }
read_fifo.c文件
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #define BUFS PIPE_BUF //PIPE_BUF管道默认一次性读写的数据长度
- int main(void)
- {
- int fd;
- int len;
- char buf[BUFS];
- mode_t mode=0666;
- if((fd=open("fifo1",O_RDONLY))<0)
- {
- perror("open");
- exit(1);
- }
- while((len=read(fd,buf,BUFS))>0)
- printf("read_fifo read:%s",buf);
- close(fd);
- exit(0);
- }
read_fifo.c使用while循环从FIFO中读取数据,在读取FIFO管道数据时,默认一次读取PIPE_BUF个字节,当管道中数据多于PIPE_BUF个字节时,一次性读出PIPE_BUF-1个字节,然后read函数返回。
上述例子可以扩展成客户端与服务器通信的实例,write_fifo类似于客户端,可以打开多个客户端向一个服务器发送请求信息,read_fifo类似于服务器,实时监控者FIFO的读出端,当有数据时,读出并进行处理,但前提是,每一个客户端必须预先知道服务器提供的FIFO接口。
4.FIFO的缺点
客户端向服务器发送请求,前提是要知道一个公共的FIFO通道,对于服务器回传应答到客户端,可以通过为每个客户端创建一专用的FIFO,来实现应答回传。这样,服务器如果要应答成千上万个客户端,创建太多的FIFO会使系统负载过大。
阅读(1025) | 评论(0) | 转发(2) |