Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2159588
  • 博文数量: 438
  • 博客积分: 3871
  • 博客等级: 中校
  • 技术积分: 6075
  • 用 户 组: 普通用户
  • 注册时间: 2011-09-10 00:11
个人简介

邮箱: wangcong02345@163.com

文章分类

全部博文(438)

文章存档

2017年(15)

2016年(119)

2015年(91)

2014年(62)

2013年(56)

2012年(79)

2011年(16)

分类: LINUX

2016-02-16 11:45:43

1. FIFO与PIPE的不同
    a. mkfifo只是创建了一个fifo文件,还需要open之后才可以调用read/write
       PIPE后可以直接调用read/write
   b. FIFO退出时要调用unlink去删除文件,否则下次调用mkfifo时会失败,
       PIPE没有创建文件,就谈不上删除不删除了
1.1 mkfifo后open
  1. 打开FIFO文件和普通文件的区别有2点:
  2. 第一个是不能以O_RDWR模式打开FIFO文件进行读写操作。这样做的行为是未定义的。
  3. 因为我们通常使用FIFO只是为了单向传递数据,所以没有必要使用这个模式。
  4. 如果确实需要在程序之间双向传递数据,最好使用一对FIFO或管道,一个方向使用一个。或者采用先关闭在重新打开FIFO的方法来明确改变数据流的方向。
  5. 第二是对标志位的O_NONBLOCK选项的用法。
  6. 使用这个选项不仅改变open调用的处理方式,还会改变对这次open调用返回的文件描述符进行的读写请求的处理方式。
  7. O_RDONLY、O_WRONLY和O_NONBLOCK标志共有四种合法的组合方式:
  8. flags=O_RDONLY:open将会调用阻塞,除非有另外一个进程以写的方式打开同一个FIFO,否则一直等待。
  9. flags=O_WRONLY:open将会调用阻塞,除非有另外一个进程以读的方式打开同一个FIFO,否则一直等待。
  10. flags=O_RDONLY|O_NONBLOCK:如果此时没有其他进程以写的方式打开FIFO,此时open也会成功返回,此时FIFO被读打开,而不会返回错误。
  11. flags=O_WRONLY|O_NONBLOCK:立即返回,如果此时没有其他进程以读的方式打开,open会失败打开,此时FIFO没有被打开,返回-1。
  12. 这部分内容这转自 《【Linux】进程间通信-命名管道FIFO》
      http://blog.csdn.net/xiajun07061225/article/details/8471777
2.FIFO的代码
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4. #include <sys/types.h>
  5. #include <sys/stat.h>
  6. #include <string.h>
  7. #include <fcntl.h>

  8. #define FIFO1 "/tmp/fifo1"
  9. #define FIFO2 "/tmp/fifo2"

  10. //child--->fifo1-->parent
  11. //child<---fifo2<--parent
  12. void parent_process(int readfd, int writefd);
  13. void child_process(int readfd, int writefd);

  14. int main ( int argc, char *argv[] )
  15. {
  16.     int readfd, writefd;
  17.     pid_t childpid;
  18.     //int mkfifo(const char *pathname, mode_t mode);
  19.     if(mkfifo(FIFO1,0666) < 0)        //后面的0666就是创建/tmp/fifo1的文件权限--> prw-rw-r--
  20.     {
  21.         unlink(FIFO1);
  22.         perror("mkfifo1 error");
  23.         return -1;
  24.     }

  25.     if(mkfifo(FIFO2,0666) < 0)
  26.     {
  27.         unlink(FIFO2);
  28.         perror("mkfifo2 error");
  29.         return -1;
  30.     }

  31.     printf("next fork\n");
  32.     if( (childpid = fork()) < 0)
  33.     {
  34.         perror("fork error\n");
  35.         return -1;
  36.     } else if(childpid==0) //child
  37.     {
  38.         printf("child\n");
  39.         readfd = open(FIFO1, O_RDONLY, 0);             //对FIFO1-->read
  40.         writefd = open(FIFO2, O_WRONLY, 0);            //对FIFO2-->write
  41.         printf("child process\n");                     //child与parent的read/write顺序一定不能颠倒
  42.         child_process(readfd, writefd);                //否则会一直阻塞        
  43.         exit(0);
  44.     } else if(childpid > 0) //parent
  45.     {
  46.         printf("parent\n");
  47.         writefd = open(FIFO1, O_WRONLY, 0);           //对FIFO1-->write
  48.         readfd = open(FIFO2, O_RDONLY, 0);            //对FIFO2-->read
  49.  
  50.         printf("parent process\n");
  51.         parent_process(readfd, writefd);
  52.         
  53.         printf("next waitpid\n");
  54.         waitpid(childpid, NULL, 0);
  55.         printf("waitpid over\n");
  56.         close(readfd);
  57.         close(writefd);
  58.         unlink(FIFO1);
  59.         unlink(FIFO2);
  60.     }
  61.     return EXIT_SUCCESS;
  62. }

  63. void parent_process(int readfd, int writefd)
  64. {
  65.     char buf[1024];
  66.     printf("next parent read\n");
  67.     read(readfd, buf, sizeof(buf));
  68.     printf("parent read_buf=%s",buf);

  69.     sleep(1);
  70.     write(writefd, "hello,world222\n",strlen("hello,world222\n")+1);
  71. }

  72. void child_process(int readfd, int writefd)
  73. {
  74.     char buf[1024];
  75.     sleep(1);
  76.     printf("next child write\n");
  77.     write(writefd, "hello,world111\n",strlen("hello,world111\n")+1);

  78.     printf("next child read\n");
  79.     read(readfd, buf, sizeof(buf));
  80.     printf("child read_buf=%s",buf);
  81. }
注意: fork后若child先执行,read_FIFO1 
        child:      read_FIFO1 阻塞直到parent有write_FIFO1
        parent:   write_FIFO1
注意: fork后若parent先执行,read_FIFO1 
        parent:      write_FIFO1 阻塞直到child有read_FIFO1
        child:         read_FIFO1
3.改进版
在mkfifo之前需要先检查文件是否存在,若存在要先删除才可以mkfifo
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4. #include <sys/types.h>
  5. #include <sys/stat.h>
  6. #include <string.h>
  7. #include <fcntl.h>

  8. #define FIFO1 "/tmp/fifo1"
  9. #define FIFO2 "/tmp/fifo2"

  10. //child--->fifo1-->parent
  11. //child<---fifo2<--parent
  12. void parent_process(int readfd, int writefd);
  13. void child_process(int readfd, int writefd);

  14. int main ( int argc, char *argv[] )
  15. {
  16.     int readfd, writefd;
  17.     pid_t childpid;
  18.     //1. del existed FIFO
  19.     if(0 == access(FIFO1, F_OK))
  20.     {
  21.         printf("FIFO1 exist\n");
  22.         unlink(FIFO1);
  23.     }
  24.     if(0 == access(FIFO2, F_OK))
  25.     {
  26.         printf("FIFO2 exist\n");
  27.         unlink(FIFO2);
  28.     }
  29.     //2. then mkfifo
  30.     if(mkfifo(FIFO1,0666) < 0)
  31.     {
  32.         unlink(FIFO1);
  33.         perror("mkfifo1 error");
  34.         return -1;
  35.     }

  36.     if(mkfifo(FIFO2,0666) < 0)
  37.     {
  38.         unlink(FIFO2);
  39.         perror("mkfifo2 error");
  40.         return -1;
  41.     }
  42.     //3.fork
  43.     printf("next fork\n");
  44.     if( (childpid = fork()) < 0)
  45.     {
  46.         perror("fork error\n");
  47.         return -1;
  48.     } else if(childpid==0) //child
  49.     {
  50.         printf("child\n");
  51.         readfd = open(FIFO1, O_RDONLY, 0);
  52.         writefd = open(FIFO2, O_WRONLY, 0);
  53.         printf("child process\n");
  54.         child_process(readfd, writefd);
  55.         exit(0);
  56.     } else if(childpid > 0) //parent
  57.     {
  58.         printf("parent\n");
  59.         writefd = open(FIFO1, O_WRONLY, 0);
  60.         readfd = open(FIFO2, O_RDONLY, 0);

  61.         printf("parent process\n");
  62.         parent_process(readfd, writefd);
  63.         
  64.         printf("next waitpid\n");
  65.         waitpid(childpid, NULL, 0);
  66.         printf("waitpid over\n");
  67.         close(readfd);
  68.         close(writefd);
  69.         unlink(FIFO1);
  70.         unlink(FIFO2);
  71.     }
  72.     return EXIT_SUCCESS;
  73. }

  74. void parent_process(int readfd, int writefd)
  75. {
  76.     char buf[1024];
  77.     printf("next parent read\n");
  78.     read(readfd, buf, sizeof(buf));
  79.     printf("parent read_buf=%s",buf);

  80.     sleep(1);
  81.     write(writefd, "hello,world222\n",strlen("hello,world222\n")+1);
  82. }

  83. void child_process(int readfd, int writefd)
  84. {
  85.     char buf[1024];
  86.     sleep(1);
  87.     printf("next child write\n");
  88.     write(writefd, "hello,world111\n",strlen("hello,world111\n")+1);

  89.     printf("next child read\n");
  90.     read(readfd, buf, sizeof(buf));
  91.     printf("child read_buf=%s",buf);
  92. }
先删除fifo文件后再mkfifo
阅读(1426) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~