Chinaunix首页 | 论坛 | 博客
  • 博客访问: 683041
  • 博文数量: 516
  • 博客积分: 4119
  • 博客等级: 上校
  • 技术积分: 4288
  • 用 户 组: 普通用户
  • 注册时间: 2012-10-30 17:29
文章分类

全部博文(516)

文章存档

2014年(4)

2013年(160)

2012年(352)

分类:

2012-11-01 11:21:07

原文地址:管道(二)--FIFO管道 作者:graylocus

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

点击(此处)折叠或打开

  1. #include <unistd.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <fcntl.h>
  5. #include <sys/types.h>
  6. #include <sys/stat.h>
  7. #include <errno.h>
  8. #include <limits.h>

  9. #define BUFS PIPE_BUF //PIPE_BUF管道默认一次性读写的数据长度

  10. int main(void)
  11. {
  12.     int fd;
  13.     int n,i;
  14.     char buf[BUFS];
  15.     
  16.     time_t tp;
  17.     
  18.     printf("I am %d\n",getpid());
  19.     
  20.     if((fd=open("fifo1",O_WRONLY))<0) //只写打开FIFO1
  21.     {
  22.         perror("open");
  23.         exit(1);
  24.     }
  25.     
  26.     for(i=0;i<10;i++)
  27.     {
  28.         time(&tp);
  29.         n=sprintf(buf,"write_info %d sends %s",getpid(),ctime(&tp));
  30.         printf("send msg:%s\n",buf);
  31.         
  32.         if(write(fd,buf,n+1)<0){//写入到FIFO中
  33.          perror("write");
  34.          close(fd);  //写入FIFO失败,则关闭fifo文件
  35.          exit(1);
  36.         }
  37.         sleep(3);   //进程睡眠3秒
  38.     }
  39.     
  40.     close(fd);
  41.     exit(0);
  42. }

read_fifo.c文件

点击(此处)折叠或打开

  1. #include
  2. #include
  3. #include
  4. #include
  5. #include
  6. #include
  7. #include
  8. #include
  9. #define BUFS PIPE_BUF //PIPE_BUF管道默认一次性读写的数据长度
  10. int main(void)
  11. {
  12. int fd;
  13. int len;
  14. char buf[BUFS];
  15. mode_t mode=0666;
  16. if((fd=open("fifo1",O_RDONLY))<0)
  17. {
  18. perror("open");
  19. exit(1);
  20. }
  21. while((len=read(fd,buf,BUFS))>0)
  22. printf("read_fifo read:%s",buf);
  23. close(fd);
  24. exit(0);
  25. }

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会使系统负载过大。 
阅读(139) | 评论(0) | 转发(0) |
0

上一篇:管道(一)

下一篇:线程与进程

给主人留下些什么吧!~~