文章目录

  • FIFO 通信特点
  • 系统调用接口
  • 应用
    • 拥有亲缘关系之间的进程通信
    • 非亲缘关系进程之间的通信
  • 总结

FIFO 通信特点

  • FIFO文件有文件名

    • 可以像普通文件一样存储在文件系统之中
    • 可以像普通文件一样使用open/write读写
    • 和pipe文件一样属于流式文件,不能使用lseek系统调用重定位文件偏移地址
  • 具有写入原子性,支持多个进程同时对FIFO进行写操作,如日志系统/var/log
  • First in First out,先入先出。最先被写入的数据最先被读出来
    • 默认阻塞读,阻塞写的特性。可以在open的时候进行设置
    • 如果一个进程打开fifo的一端时,令一端没有打开,该进程会被阻塞。

fifo与pipe最大的区别就是pipe只能用于亲缘进程之间的通信(fork方式创建的父子进程),但是fifo可以支持任意两个进程之间的通信,并包括拥有亲缘关系的进程

系统调用接口

  • shell命令:mkfifo pathname,可以通过man mkfifo查看命令用法
  • 函数接口:int mkfifo(const char *pathname,mode_t mode)
  • 函数功能:创建fifo的有名管道
  • 函数参数:
    - pathname FIFO管道文件名
    - mode 读写权限

应用

拥有亲缘关系之间的进程通信

通信过程类似于pipe的fd[0]读出,fd[1]写入


#include <sys/types.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <stdio.h>#define FIFO "testfifo"
int main()
{int a=mkfifo(FIFO,0644);if (0 != a)printf("mkfifo failed %d\n",a);int ret,fifo_fd;ret = fork();if (ret == -1) {perror("fork");_exit(-1);}//子进程负责写入管道else if (ret == 0) {fifo_fd = open("testfifo",O_RDWR);char buf[100];memset(buf,0,100);printf("child process(%d) input msg:",getpid());//scanf("%s",buf);fgets(buf,10,stdin);int write_len = write(fifo_fd,buf,strlen(buf));printf("%d bytes has been sent\n",write_len);_exit(1);}//父进程进行从管道进行读取else {sleep(5);fifo_fd = open("testfifo",O_RDWR);char buf[100];memset(buf,0,100);printf("father process befor read\n");int read_len = read(fifo_fd,buf,100);if (read_len == -1)printf("read error %d\n",read_len);printf("father process(%d) read message from fifo :%s\n",getpid(),buf);_exit(1);}return 0;
}
非亲缘关系进程之间的通信

写端:


#include <stdio.h>
#include <unistd.h>
#include <strings.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>#define FIFO_NAME "testfifo"int main(int argc, char* argv[])
{int fd;char buf[100];mkfifo(FIFO_NAME, S_IFIFO|0666);//循环向testinfo中写入数据while (1){printf("please input the string : \n");fd = open(FIFO_NAME, O_WRONLY);fgets(buf,100,stdin);write(fd, buf, strlen(buf)+1);close(fd);}unlink(FIFO_NAME); //删除命名管道文件sleep(1);return 0;
}

读端:

#include <stdio.h>
#include <unistd.h>
#include <strings.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>#define FIFO_NAME "testfifo"
#define BUF_SIZE 1024int main(int argc, char* argv[])
{int fd;char buf[BUF_SIZE];//循环从testinfo中读取数据while (1) {fd = open(FIFO_NAME, O_RDONLY);//read系统调用会从打开的文件当前文件偏移地址开始读,即上次写入的数据read(fd, buf, BUF_SIZE);printf("%s\n", buf);close(fd);}return 0;
}

总结

为什么无名管道只能用于父子进程之间的通信呢?无名管道是一个文件,但是只能存在与内存之中,且该文件的读写方式是固定的,我们只能从一端写入,一端读出。使用无名管道通信,他得文件句柄需要在同一个进程内共享。即在同一个进程内只有fork的方式,能够将当前进程所有文件描述符以及进程状态信息拷贝给另一个进程;只有在这样的进程关系之下,无名管道的数据传输才能实现一端写入,一端读出。

命名管道fifo可以像普通文件一样存在与操作系统磁盘之中,同样支持read/write的数据读写,因此它能够被多个进程共同访问。虽然fifo相比于pipe使用范围扩大了,但是总体的阻塞式通信依然存在。

pipe的内核实现fs/pipe.cpipe_readpipe_write函数处理过程中都是通过加锁mutex来实现,并没有相关的异步操作,而fifo的fifo_open函数同样是阻塞式处理函数体。

linux进程间通信:命名管道FIFO相关推荐

  1. linux 进程间通信 命名管道FIFO的原理与使用

    参考文章1:管道 pipe是什么?(进程通信的一种方式)(可以先大致了解管道) 参考文章2:FIFO(命名管道) FIFO常被称为命名管道,以区分管道(pipe).管道(pipe)只能用于" ...

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

    命名管道概述 如果我们要在不相关的进程间交换数据,那么使用FIFO文件将会十分方便. FIFO文件通常也称为命名管道(named pipe).命名管道是一种特殊类型的文件,它在文件系统中以文件名的形式 ...

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

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

  4. linux命名管道通信方式图例,linux IPC 命名管道

    在前面一篇文章中[Linux进程间通信] - 匿名管道中,我们介绍了Linux/Unix系统中最古老的一种进程间通信方式 – 匿名管道.此外,我们也讲解了匿名管道的几个局限性,特别是匿名管道只能用于父 ...

  5. java mkfifo_命名管道FIFO和mkfifo函数

    进程间通信必须通过内核提供的通道,而且必须有一种办法在进程中标识内核提供的某个通道,前面讲过的匿名管道是用打开的文件描述符来标识的.如果要互相通信的几个进程没有从公共祖先那里继承文件描述符,它们怎么通 ...

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

    目录 概述 IPC 对象的持续性 什么是管道 读取外部程序的输出 将输出送往 popen 传递更多的数据 如何实现 popen pipe 调用 跨越 fork 调用管道 父进程和子进程 管道关闭后的读 ...

  7. linux pipe 命名管道,linux 进程学习笔记-named pipe (FIFO)命名管道

    与"无名管道"不同的是,FIFO拥有一个名称来标志它,所谓的名称实际上就是一个路径,比如"/tmp/my_fifo",其对应到磁盘上的一个管道文件,如果我们用f ...

  8. linux系统编程之管道(三):命名管道FIFO和mkfifo函数

    进程间通信必须通过内核提供的通道,而且必须有一种办法在进程中标识内核提供的某个通道,前面讲过的匿名管道是用打开的文件描述符来标识的.如果要互相通信的几个进程没有从公共祖先那里继承文件描述符,它们怎么通 ...

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

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

最新文章

  1. Unity从头开始开发增强现实(AR)游戏学习教程
  2. 公布硕士论文最新进展一(2007.3.6)
  3. C++string类知识点总结
  4. 网络协议图形化分析工具EtherApe
  5. qt widget 窗口拉伸_QTDesigner的QVBoxLayout自动随窗口拉伸
  6. LeetCode面试刷题技巧-二分查找算法代码思路解析
  7. 蓝桥杯-数字三角形 (java)
  8. docker 限制容器日志大小
  9. Java黑皮书课后题第6章:*6.14(估算π)π可以使用下面的数列进行计算。编写一个方法,对于给定的i返回m(i),并编写一个测试程序,显示如下表格
  10. MyBatis配置:在控制台打印SQL语句
  11. python集合类型运算符_Python 数据类型和运算符
  12. python tracer函数_Python流程控制常用工具和函数定义
  13. Best of Best系列(1)——CVPR
  14. Tsys1.1使用经验(汇集中)
  15. 京瓷1020怎么打印自检页_惠普打印机怎样打印测试页
  16. (二)电子器件、电子技术和电子电路
  17. 一代测序、二代测序以及三代测序的优缺点及应用对比?
  18. Fantastic-Matplotlib 第一回
  19. r340服务器怎么接显示器,笔记本电脑如何连显示器_笔记本怎么链接显示器
  20. ORA-12805: parallel query server died unexpectedly ORA-04030 (sort subheap,sort key) 原因排查与解决方法

热门文章

  1. layoutSubviews总结(转)
  2. C++ Windows进程管理
  3. 信号量,互斥锁,条件变量的联系与区别
  4. 小程序真机调试访问不了接口_小程序入门
  5. c语言n1=(n2=(n3=0)),计算机二级C语言考试选择题(带答案)
  6. php 字符串排序 带数组,php – 按字符串排序的多维数组
  7. ajax异步提交 java_jquery ajax异步提交表单数据的方法
  8. Pycharm问题归纳
  9. 和12岁小同志搞创客开发:手撕代码,做一款数字骰子
  10. 力扣(LeetCode)刷题,简单+中等题(第33期)