管道作为进程间通信的最古老方式,它的缺点是没有名字,因此仅仅能用在有亲缘关系的父子进程之间。对于无亲缘关系的进程间。无法用管道进行通信。FIFO能够完毕无亲缘关系的进程间的通信。FIFO也被称为命名管道。它是一种特殊类型的文件。在文件系统中以文件名称的形式存在,但它的行为却和上面提到的管道类似。

创建命名管道有两种方法:

1、在命令行上运行命令:mkfifo filename 来创建FIFO。

2、使用mkfifo函数创建FIFO。

  1. #include <sys/stat.h>
  2. #include <sys/types.h>
  3. int mkfifo(const char *pathname, mode_t mode); //返回值:若成功则返回0,若出错则返回-1

注意。mkfifo函数仅仅是创建FIFO,要想打开它。还必须使用open函数。并且创建的过程中是隐含了O_CREAT| O_EXCL标志的,也就是说它要么创建一个新的FIFO,要么返回一个EEXIST错误。假设不希望创建一个新的FIFO,就改调用open而不是mkfifo。要打开一个已存在的FIFO或创建一个新的FIFO,应先调用mkfifo。再检查它是否返回EEXIST错误,若返回该错误则改为调用open。FIFO不能打来来既读又写,由于它是半双工的。

FIFO与管道的差别主要有下面两点:

1、创建并打开一个管道仅仅须要调用pipe。创建并打开一个FIFO则须要调用mkfifo后再调用open。

2、管道在全部进程终于都关闭它之后自己主动消失。

FIFO的名字则仅仅有调用unlink才从文件系统中删除。

管道与FIFO都有系统加在他们上面的限制:

1、OPEN_MAX 一个进程在随意时刻打开的最大描写叙述符数。

2、PIPE_BUF 可原子地写一个管道或FIFO的最大数据量。

以下就以样例来学习FIFO的创建、訪问、打开等操作。

创建方法一mkfifo命令:

  1. book@book-desktop:/work/tmp/unp$ mkfifo my_file //利用mkfifo命令创建my_file命名管道
  2. book@book-desktop:/work/tmp/unp$ ls -l my_file
  3. prw-r--r-- 1 book book 0 2014-07-03 15:44 my_file //利用ls命令查看上一条命令创建的my_file命名管道
  4. book@book-desktop:/work/tmp/unp$ mkfifo my_file
  5. mkfifo: cannot create fifo `my_file': File exists //由于命名管道已经存在,所以此时的mkfifo命令失败

创建方法二mkfifo函数:

将上面的命名管道删除后,利用以下的语句又一次创建my_file命名管道。

  1. int res = mkfifo("my_file", 0777);
  2. if(res == 0) printf("FIFO created\n");
  3. exit(EXIT_SUCCESS);

查看结果例如以下:

  1. book@book-desktop:/work/tmp/unp$ rm -rf my_file
  2. book@book-desktop:/work/tmp/unp$ ls
  3. a.out fifo.c mutex pipemesg unpv22e
  4. fifo fifocliserv pipe pxmsg unpv22e.tar.gz
  5. book@book-desktop:/work/tmp/unp$ ./a.out
  6. FIFO created
  7. book@book-desktop:/work/tmp/unp$

訪问上面创建的FIFO:

cat < my_file,由于此时FIFO里没有不论什么数据。所以此时堵塞。

echo "Hello world." > my_file,由于没有echo等待其它进程读取数据。所以相同堵塞。

使用open打开FIFO文件:

1、打开FIFO的主要限制是,程序不能以O_RDWR模式打开FIFO文件进行读写操作,由于通常我们仅仅是单向传递数据。假设须要双向传递数据,就要创建一对FIFO。

实现实例请參考之前写的客户-server程序,点此进入

2、打开FIFO文件和打开普通文件的还有一个差别是。对open_flag的O_NOBLOCK选项的使用方法。使用这个选项不仅改变open调用的处理方式。还会改变对这次open调用返回的文件描写叙述符进行的读写请求的处理方式。

a、open(const char *path, O_RDONLY);这样的情况下。open调用将堵塞,除非有一个进程以写方式打开同一个FIFO。否则不会返回。

比如上面的cat命令的样例。

b、open(const char *path,O_RDONLY | O_NONBLOCK);即使没有其它进程以写方式打开FIFO,这个open调用也将成功马上返回。

c、open(const char *path, O_WRONLY); open调用将堵塞,知道有一个进程以读的方式打开同一个FIFO为止。如上面的echo命令的样例。

d、open(const char *path, O_WRONLY | O_NONBLOCK);函数马上返回。但假设没有进程以读方式打开FIFO。open调用将返回一个错误而且FIFO也不会被打开。

演示样例代码:

  1. #include <unistd.h>
  2. #include <stdlib.h>
  3. #include <stdio.h>
  4. #include <string.h>
  5. #include <fcntl.h>
  6. #include <sys/types.h>
  7. #include <sys/stat.h>
  8.  
  9. #define FIFO_NAME "my_file"
  10.  
  11. int
  12. main(int argc, char **argv)
  13. {
  14. int res;
  15. int open_mode = 0;
  16. int i;
  17.  
  18. if(argc < 2){
  19. fprintf(stderr, "Usage : %s <some combinations of\
  20. O_RDONLY O_WRONLY O_NONBLOCK>\n", *argv);
  21. exit(EXIT_FAILURE);
  22. }
  23.  
  24. for(i = 1; i < argc; i++){
  25. if(strncmp(*++argv , "O_RDONLY", 8) == 0);
  26. open_mode |= O_RDONLY;
  27. if(strncmp(*++argv , "O_WRONLY", 8) == 0);
  28. open_mode |= O_WRONLY;
  29. if(strncmp(*++argv , "O_NONBLOCK", 10) == 0);
  30. open_mode |= O_NONBLOCK;
  31. }
  32.  
  33. if(access(FIFO_NAME, F_OK) == -1){
  34. res = mkfifo(FIFO_NAME, 0777);
  35. if(res != 0){
  36. fprintf(stderr, "Could not create fifo %s\n", FIFO_NAME);
  37. exit(EXIT_FAILURE);
  38. }
  39. }
  40.  
  41. printf("Process %d opending FIFO\n", getpid());
  42. res = open(FIFO_NAME, open_mode);
  43. printf("Process %d result %d\n", getpid(), res);
  44. sleep(5);
  45. if(res != -1) close(res);
  46. printf("Process %d finished\n", getpid());
  47. exit(EXIT_SUCCESS);
  48. }

对于FIFO的高级一点的应用。比方客户-server程序,进程间通信等,參见直接的总结,点此链接

參考:

1、之前的总结:http://blog.csdn.net/to_be_it_1/article/details/28384117

2、《Linux程序设计》 Neil Matthew&&Richard Stones
3、《UNIX环境高级编程》Richard Stevenson
4、《UNIX网络编程 卷2》 Richard Stevenson

【UNIX网络编程】FIFO的更多相关文章

  1. Unix网络编程--卷二:进程间通信

    Unix网络编程--卷二:进程间通信 本书是一部Unix网络编程的经典之作!进程间通信(IPC)几乎是所有Unix程序性能的关键,理解IPC也是理解如何开发不同主机网络应用程序的必要条件.本书从对Po ...

  2. UNIX网络编程 卷2:进程间通信

    这篇是计算机类的优质预售推荐>>>><UNIX网络编程 卷2:进程间通信(第2版)> UNIX和网络专家W. Richard Stevens的传世之作 编辑推荐 两 ...

  3. 《Unix 网络编程》08:基本UDP套接字编程

    基本UDP套接字编程 系列文章导航:<Unix 网络编程>笔记 UDP 概述 流程图 recvfrom 和 sendto #include <sys/socket.h> ssi ...

  4. UNIX网络编程——getsockname和getpeername函数

    UNIX网络编程--getsockname和getpeername函数   来源:网络转载   http://www.educity.cn/linux/1241293.html     这两个函数或者 ...

  5. 【LINUX/UNIX网络编程】之简单多线程服务器(多人群聊系统)

    RT,Linux下使用c实现的多线程服务器.这个真是简单的不能再简单的了,有写的不好的地方,还希望大神轻拍.(>﹏<) 本学期Linux.unix网络编程的第四个作业. 先上实验要求: [ ...

  6. 【LINUX/UNIX网络编程】之使用消息队列,信号量和命名管道实现的多进程服务器(多人群聊系统)

    RT,使用消息队列,信号量和命名管道实现的多人群聊系统. 本学期Linux.unix网络编程的第三个作业. 先上实验要求: 实验三  多进程服务器 [实验目的] 1.熟练掌握进程的创建与终止方法: 2 ...

  7. 【Linux/unix网络编程】之使用socket进行TCP编程

    实验一 TCP数据发送与接收 [实验目的] 1.熟练掌握套接字函数的使用方法. 2.应用套接字函数完成基本TCP通讯,实现服务器与客户端的信息交互. [实验学时] 4学时 [实验内容] 实现一个服务器 ...

  8. Unix网络编程--卷一:套接字联网API

    UNIX网络编程--卷一:套接字联网API 本书面对的读者是那些希望自己编写的程序能够使用成为套接字(socket)的API进行彼此通信的人. 目录: 0.准备环境 1.简介 2.传输层:TCP.UD ...

  9. [转载] 读《UNIX网络编程 卷1:套接字联网API》

    原文: http://cstdlib.com/tech/2014/10/09/read-unix-network-programming-1/ 文章写的很清楚, 适合初学者 最近看了<UNIX网 ...

随机推荐

  1. 【左偏树+贪心】BZOJ1367-[Baltic2004]sequence

    [题目大意] 给定一个序列t1,t2,...,tn ,求一个递增序列z1<z2<...<zn , 使得R=|t1−z1|+|t2−z2|+...+|tn−zn| 的值最小.本题中,我 ...

  2. [HZOI 2016]我们爱数数

    [HZOI 2016]我们爱数数 题目大意: 一张圆桌,每个位置按顺时针从\(1\)到\(n\)编号.有\(n\)个人,编号从\(1\)到\(n\).如果编号为\(i\)的人坐到了编号为\(i\)的位 ...

  3. Shell基础学习(一) Shell简介

    Shell是什么? Shell是C语言编写的一种程序,用于用户与linux操作系统交互:Shell既是命令语言,又是程序设计语言. Shell脚本是什么? Shell脚本是用Shell编写的脚本程序. ...

  4. Dual transistor improves current-sense circuit

    In multiple-output power supplies in which a single supply powers circuitry of vastly different curr ...

  5. SourceInsight中文字体

    转载自: http://blog.chinaunix.net/uid-29094179-id-3889999.html 1.正确显示中文注释 1)Options->Style Propertie ...

  6. Android支付接入之Google In-app-Billing

    原文链接:http://www.mobile-open.com/2016/966337.html 因为公司需要接入Google的应用内支付(即Google的in-app Billing V3),接入过 ...

  7. appium+python自动化60-windows上同时启动多个appium服务,让多个android机器并行运行

    前言 做android自动化的时候,启动一个appium服务,只能匹配一个手机去自动化执行.有时候想同一套代码,可以在不同的手机上执行,测下app在不同手机上兼容性. 这就需要启动多个appium服务 ...

  8. 电子书mobi的格式详解

    https://wiki.mobileread.com/wiki/MOBI#Format Like PalmDOC, the Mobipocket file format is that of a s ...

  9. Openshift 和Harbor的集成

    1.安装配置Harbor 环境rhel 7.6 安装docker,python 安装docker-compose sudo curl -L https://github.com/docker/comp ...

  10. sqlserver 汉字转拼音

    作者不详       --方法一sqlserver汉字转拼音首字母 --调用方法 select dbo.procGetPY ('中國') Create FUNCTION dbo.procGetPY ( ...