命名管道的主要用途:不相关的进程之间交换数据。

命令行上创建命名管道:

$ mkfifo filename

 程序中创建命名管道:

#include <sys/types.h>
#include <sys/stat.h> int mkfifo(const char *filename, mode_t mode);

备注:#include <sys/types.h>是Unix/Linux系统的基本系统数据类型的头文件,含有Size_t,time_t,pid_t等类型。

   #include<sys/stat.h>是Unix/Linux系统定义文件状态所在的伪标准头文件。

例程:创建一个FIFO命名管道

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h> int main(int argc, char *argv[])
{
int res; res = mkfifo("./FIFO", );
if(res == )
{
printf("FIFO created\n");
} exit(EXIT_SUCCESS); }

备注:文件权限方面的知识有点模糊,需要回顾。

$ ls -lF(F选项会在显示目录条目时,在目录后加一个符号“/”表示文件夹 “|”表示管道)
prwxr-xr-x root root 12月 : FIFO|

创建出来的FIFO管道如上图所示,其中第一个字符p表示这是一个管道,其中最后一个|符号是由ls命令的-F选项所添加,也表示它是一个管道。

FIFO是以命名文件的形式存在,而不是打开的文件描述符,所以在对它进行读写操作之前必须先打开它。而且,对于FIFO来说,传递给open函数的第一个参数一定是一个FIFO的路径名,而不是一个文件名。

使用open打开FIFO文件

1.FIFO命名管道不能以O_RDWR的模式打开,会产生二义性。(通常使用FIFO只是为了单向传递数据)

2.如果确定需要程序之间双向传递数据。①最好使用一对FIFO或者管道,一个方向使用一个②采用先关闭再重新打开FIFO的方法来明确地改变数据流的去向(不常用)。

3.打开FIFO文件和打开普通文件的另一点区别是:对open_flag(open的第二个参数)的O_NONBLOCK的用法。

  • open(const char *path, O_RDONLY);

在这种情况下,open调用将阻塞,除非有一个进程以写方式打开一个FIFO,否则它是不会返回。

  • open(const char *path, O_RDONLY | O_NONBLOCK);

即使没有其他进程以写方式打开FIFO,open调用也会成功并且立即返回。

  • open(const char *path, WRONLY);

在这种情况下,open调用将阻塞,直到有一个进程以读方式打开进程。

  • open(const char *path,  WRONLY | O_NONBLOCK);

这个函数调用总是立刻返回,但如果没有进程以读方式打开FIFO文件,open调用将返回一个错误-1并且FIFO也不会被打开。如果确实有一个进程以读方式打开FIFO文件,那么我们就我再可以通过它返回的文件描述符对这个FIFO文件进行写操作。

  注意:由以上可知,必须先有进程以读方式打开FIFO文件,然后再有进程以写方式打开FIFO文件。

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h> /* using string */
#include <fcntl.h> /* O_RDONLY in this file */ #define FILE_NAME "/home/test/readfifo" int main(int argc, char *argv[])
{
int res;

  /* 确保文件存在 */
if(access(FILE_NAME, F_OK) == -)
{
res = mkfifo(FILE_NAME, ); if(res != )
{
printf("the fifo file could not create\n");
exit(EXIT_FAILURE);
}
} printf("read fifo file create successfull \n"); open(FILE_NAME, O_RDONLY | O_NONBLOCK); printf("open the read fifo file is success \n"); exit(EXIT_SUCCESS);
}

备注:string.h在使用到字符数组时需要使用。

        fcntl.h是unix标准中通用的头文件,其中包含相关函数有open,fcntl,shutdown,unlink,fclose等。与unistd.h相比,后者定义了更多的函数原型。

在open的函数调用中,如果是非阻塞。

read fifo file create successfull 

open the read fifo file is success 

在open的函数调用中,如果是阻塞,即没有使用O_NONBLOCK

read fifo file create successfull 

就会阻塞在open函数上,然后等待写进程打开这个函数,然后才会返回。

注意:Linux中进程被阻塞时,并不消耗CPU资源。

对FIFO进行读写操作

如果在open函数使用了O_NONBLOCK模式,会影响到对FIFO的read和write调用。

  • 对一个空的、阻塞的FIFO(即没有用O_NONBLOCK标志打开的)的read调用将等待,直到有数据可以读时才继续执行。
  • 对一个空的、非阻塞的FIFO的read调用将立刻返回0字节。
  • 对一个完全阻塞FIFO的write调用将等待,直到数据可以被写入才继续执行,如果FIFO不能接受所有写入数据,将按照下面的规则执行:①如果请求写入的数据长度小于等于PIPE_BUF字节,调用失败,数据不能写入。(表示有空间,但是不能写入,出现问题)。②如果请求写入的数据的长度大于PIPE_BUF字节,将写入部分数据,返回实际写入的字节数,返回值也可能是0(表示只是FIFO的空间不足,先写入部分数据)。

注意:PIPE_BUF是系统对FIFO的一个数据长度的限制,通常在头文件limits.h可以找到它,通常值为4096字节,也有特例。系统规定:在一个以O_WRONLY方式(即阻塞方式)打开的FIFO中,如果写入的数据长度小于等于PIPE_BUF,要么全部一次性写入,要么一个字节也不写入。

基于“注意”中的描述,如果出现一种情况:多个程序向一个FIFO中写入数据的时候,为了保证这些写入的数据不会相互交错重叠,那么就要求每次写入的数据长度要小于等于PIPE_BUF字节。

《Linux 进程间通信》命名管道:FIFO的更多相关文章

  1. Linux进程间通信-命名管道

    前面我们讲了进程间通信的一种方式,匿名管道.我们知道,匿名管道只能用于父子关系的进程之间.那么没有这种关系的进程之间该如何进行数据传递呢? 1.什么是命名管道 匿名管道是在缓存中开辟的输出和输入文件流 ...

  2. Linux - 进程间通信 - 命名管道

    1.命名管道的特点: (1)是管道,可用于非血缘关系的进程间的通信 (2)使用命名管道时,梁金成需要用路径表示通道. (3)命名管道以FIFO的文件形式存储于文件系统中.(FIFO:总是按照先进先出的 ...

  3. Linux进程间通信之管道(pipe)、命名管道(FIFO)与信号(Signal)

    整理自网络 Unix IPC包括:管道(pipe).命名管道(FIFO)与信号(Signal) 管道(pipe) 管道可用于具有亲缘关系进程间的通信,有名管道克服了管道没有名字的限制,因此,除具有管道 ...

  4. 进程间通信系列 之 命名管道FIFO及其应用实例

    进程间通信系列 之 概述与对比   http://blog.csdn.net/younger_china/article/details/15808685  进程间通信系列 之 共享内存及其实例   ...

  5. Linux学习笔记25——命名管道(FIFO)

    1 命名管道(FIFO) 管道应用的一个重大缺陷就是没有名字,因此只能用于亲缘进程之间的通信.后来从管道为基础提出命名管道(named pipe,FIFO)的概念,该限制得到了克服.FIFO不同于管道 ...

  6. 进程间通信___命名管道(FIFO)

    命名管道(FIFO) 基本概念 命名管道和一般的管道基本相同,但也有一些显著的不同: 命名管道是在文件系统中作为一个特殊的设备文件而存在的. 不同祖先的进程之间可以通过管道共享数据. 当共享管道的进程 ...

  7. 命名管道FIFO及其读写规则

    一.匿名管道的一个限制就是只能在具有共同祖先的进程间通信命名管道(FIFO):如果我们想在不相关的进程之间切换数据,可以使用FIFO文件来做这项工作注意:命名管道是一种特殊类型文件.利用命令:$ mk ...

  8. linux进程间通信-有名管道(FIFO)

    有名管道(FIFO) 命名管道也被称为FIFO文件,是一种特殊的文件.由于linux所有的事物都可以被视为文件,所以对命名管道的使用也就变得与文件操作非常统一. (1)创建命名管道 用如下两个函数中的 ...

  9. Linux 进程间通信之管道(pipe),(fifo)

     无名管道(pipe) 管道可用于具有亲缘关系进程间的通信,有名管道克服了管道没有名字的限制,因此,除具有管道所具有的功能外,它还允许无亲缘关系进程间的通信: 定义函数: int pipe(int f ...

  10. 进程间通信:命名管道FIFO(2)

    一.命名管道 如果我们想在不相关的进程之间交换数据,可以用FIFO文件来完成这项工作,它通常也被称为命名管道.命名管道是一种特殊类型的文件,它在文件系统中以文件名的形式存在,但是它的行为却和我们已经见 ...

随机推荐

  1. ZBrush中关于标记的特殊情况

    在ZBrush®中使用Marker标记调控板来记忆物体属性,因此能在任何时间回到标记并使用它给其他物体或改变物体作为参考点,在使用Marker标记调控板时回出现很多特殊情况,本文小编就这些特殊情况做一 ...

  2. Python——Day4(基础知识练习二)

    # 1.请用代码实现:利用下划线将列表的每一个元素拼接成字符串.# li = ['alex','eric','rain']# li = ['alex','eric','rain']# li2 = &q ...

  3. Vue.mixin Vue.extend(Vue.component)的原理与区别

    1.本文将讲述 方法 Vue.extend Vue.mixin 与 new Vue({mixins:[], extend:{}})的区别与原理 先回顾一下 Vue.mixin 官网如下描述: Vue. ...

  4. 开发微信小程序必须要知道的事

    为什么是小程序? 为什么我们会开发小程序呢?或许是因为工作需要,或许是源于自己的追求(来自名利的欲望),但我要说--这是一种缘分,很美好的缘分,很多年后还值得庆幸的缘分 小程序目前可以分为三个阶段 一 ...

  5. HTML 编码规范

    语法 使用 4 个空格做为一个缩进层级,不允许使用 2 个空格或 tab 字符 在属性上,使用双引号 "",不要使用单引号 '' 属性名 / 属性值全小写,用中划线 - 做分隔符 ...

  6. GitHub上搭建私人hexo博客操作教程

    GitHub上搭建hexo博客 安装GitGit:主要用于上传博客页面到github和命令操作安装NodeNode.js:Hexo的运行环境安装HexoHexo:博客程序打开安装Git后的生成的右键菜 ...

  7. 20个C#热点问题

  8. Scratch单机版下载

    Scratch单机版下载 这两个地址速度比较快: Adobe Air:http://7dx.pc6.com/wwb5/AdobeAIR2800127.zip Scratch :http://7dx.p ...

  9. EMERGENCY! EUREKA MAY BE INCORRECTLY CLAIMING INSTANCES ARE UP WHEN THEY'RE NOT. RENEWALS ARE LESSER

    EMERGENCY! EUREKA MAY BE INCORRECTLY CLAIMING INSTANCES ARE UP WHEN THEY'RE NOT. RENEWALS ARE LESSER ...

  10. jQuery中focusin()和focus()、find()和children()的差别

    jQuery中focus()和focusin().focus()和children()的差别 focus()和focusin() focus()和focusin()的差别在于focusin()支持事件 ...