目录

概述

要点

1 虽然fifo是一个文件,但是两个进程使用fifo时,各自都要用open函数打开fifo。

2 open有读写等多种模式。此外模式之间还可以组合。

读(O_RDONLY),不论是否阻塞

写+阻塞(O_WRONLY)

写+非阻塞(O_WRONLY | O_NONBLOCK)

3 程序启动次序

4 程序退出

代码

主进程:

子进程:


概述

管道适用于进程间通信。按照陈硕所著的《Linux多线程服务端编程:使用muduo C++网络库》3.4节的说法,“进程间最好使用TCP”。但是在实际工作中,由于各种原因,我还是喜欢使用管道或者其他方式完成进程间通信。

这里给出一个命名管道的通信示例。命名管道fifo是一个文件,在程序master(主进程)中创立,其名字由mkfifo函数定下来。主进程负责写入数据到管道。程序slave(子进程)负责读取数据,并显示。退出时,用户要在主进程中键入quit指令。两个进程各自使用close函数结束对fifo的访问。并且由读进程调用unlink函数删除fifo文件。

两个程序各自占据一个console。

要点

1 虽然fifo是一个文件,但是两个进程使用fifo时,各自都要用open函数打开fifo。

2 open有读写等多种模式。此外模式之间还可以组合。

读(O_RDONLY),不论是否阻塞

open处于读模式下,尝试打开一个不存在的fifo将导致open直接返回-1,打开失败。

写+阻塞(O_WRONLY)

open处于写模式+阻塞下,假如子进程还没有用读模式的open来打开fifo,则写模式的open将阻塞,直到fifo被子进程读模式的open打开。

写+非阻塞(O_WRONLY | O_NONBLOCK)

open处于写模式+非阻塞下,假如子进程还没有用读模式的open来打开fifo,则写模式的open将直接返回-1,打开失败。

3 程序启动次序

在fifo没有创建时就让slave文件(子进程)open管道,尝试打开一个不存在的fifo将导致open直接返回-1,打开失败。下面的截图展示了这个情况:

所以应该先启动主进程来创建mkfifo。

open处于写模式+阻塞下试图打开fifo,假如子进程还没有用读模式的open来打开fifo,则写模式的open将阻塞,直到fifo被子进程读模式的open打开。下图展示了主进程(右)的阻塞。

只有在主进程先启动,随后启动子进程的情况下,两个进程的open才会先后成功打开fifo:

4 程序退出

两个进程都要在退出前调用close函数关闭fifo文件。此外,读进程在close之后还要调用unlink删除fifo文件。

代码

主进程:

#include <sys/types.h>
#include <sys/stat.h>
#include <sys/fcntl.h>
#include <unistd.h>
#include <string.h>
#include <iostream>
#include <stdio.h>const char * pFifoName = "fifoM";int main(void)
{if(access(pFifoName, F_OK) == -1){//检查fifo文件是否存在,不存在就创建一个mkfifo(pFifoName, 0644);}int p = open(pFifoName, O_WRONLY);if(p != -1){//假如读管道的进程还没就打开写模式的管道文件,则open将阻塞直到读进程启动std::cout<<"open"<<std::endl;char readin[128];while(true){std::cin.getline(readin, 127);readin[127]=0;//printf("%d %d cease\n", readin[4], readin[6]);if(strcmp("quit", readin) == 0) {             break;}write(p, readin, strlen(readin));}close(p);}return 0;
}

子进程:

#include <sys/types.h>
#include <sys/stat.h>
#include <sys/fcntl.h>
#include <unistd.h>
#include <string.h>
#include <iostream>
#include <stdio.h>
#include <errno.h>const char * pFifoName = "fifoM";int main(void)
{int p = open(pFifoName, O_RDONLY | O_NONBLOCK);if(p != -1){char recv[128];while(true){int iRet = read(p, recv, 127);if(-1 == iRet){if(errno == EAGAIN){//std::cout<<"again"<<std::endl;//非阻塞模式下,假如read读不到数据(fifo没有数据),则进入这个分支}else{break;}}else if(iRet > 0){recv[iRet] = 0;std::cout<<recv<<std::endl;}else if(0 == iRet){//假如写进程退出了,则iRet返回0//std::cout<<"0read"<<std::endl;break;}else{break;}}close(p);std::cout<<"break;"<<std::endl;unlink(pFifoName); //删除文件}else{std::cout<<"fail to open"<<std::endl;}return 0;
}

linux命名管道fifo通信示例相关推荐

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

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

  2. linux进程间通信:命名管道FIFO

    文章目录 FIFO 通信特点 系统调用接口 应用 拥有亲缘关系之间的进程通信 非亲缘关系进程之间的通信 总结 FIFO 通信特点 FIFO文件有文件名 可以像普通文件一样存储在文件系统之中 可以像普通 ...

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

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

  4. 开发日记-20190823 linux有名管道fifo,进程间通信

    转载于和感谢:linux有名管道fifo,进程间通信 命名管道(FIFO)不同于无名管道之处在于它提供了一个路径名与之关联,以 FIFO 的文件形式存在于文件系统中,这样,即使与 FIFO 的创建进程 ...

  5. 本地对弈五子棋(以命名管道进行通信)

    初步的界面如下: 为了实现不同的窗口.不同进程弈五子棋对弈,就需要在不同进程间的进行通信,我们采用linux底层的命名管道进行通信. 首先我们要进行管道通信头文件的包含.传输数据的结构定义.数据通信操 ...

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

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

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

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

  8. linux 命名管道 c语言 不同进程,进程间通信 - 命名管道实现

    命名管道概述 命名管道是通过网络来完成进程之间的通信的,命名管道依赖于底层网络接口, 其中包括有 DNS 服务,TCP/IP 协议等等机制,但是其屏蔽了底层的网络协议细节, 对于匿名管道而言,其只能实 ...

  9. linux 命名管道通信速度,《Linux 进程间通信》命名管道:FIFO

    命名管道的主要用途:不相关的进程之间交换数据. 命令行上创建命名管道: $ mkfifo filename 程序中创建命名管道: #include #include int mkfifo(const ...

  10. 进程间的通信(二)命名管道fifo

    在linux下我们先通过一个实例来说明一下mkfifo 的作用, 然后再看mkfifo 的使用详解 # mkfifo myfifo # ping edu.cn >> myfifo 另开一个 ...

最新文章

  1. CSP认证201509-4 高速公路[C++题解]:强连通分量、tarjan算法模板题
  2. Google开源项目风格指南-笔记
  3. MySQL局域网内访问慢的原因及解决方法
  4. 嵌入式开发中C语言编程要点简述!
  5. Android 跳转到ViewPager指定页面
  6. nodemailer使用_如何使用Nodemailer使用HTML作为内容发送电子邮件 Node.js
  7. HTML5营销代理商设计机构网站模板
  8. Python 爬取 620 首虾米歌曲,揭秘五月天为什么狂吸粉?!
  9. 智能小区计算机网络系统,智能住宅小区综合布线系统方案
  10. 信息系统项目管理---第九章 项目人力资源管理
  11. 如何安装Eclipse WTP插件
  12. 小学计算机画图课件第一册,第一册信息技术课件-第三章 第1课 认识“画图”软件 甘少版(共12张PPT)...
  13. 推广链接生成html操作流程,拼多多生成商城推广链接接口
  14. 测试用例大体上包含哪些内容?
  15. win10查看本机密钥的方法
  16. vscode能写winform窗体吗_VSCode——愉快的写C#
  17. IE10和IE9兼容性常见问题解答(FAQ)
  18. 服务器做网站空间,用服务器做网站空间
  19. 个人日常开发工具、问题收集
  20. c语言编程计算π的值

热门文章

  1. 利用Java实现简单的日报管理
  2. C语言进行可视化编程
  3. css的checkbox样式,css自定义checkbox样式的方法总结
  4. Android相机开发实战
  5. 《Oracle 11g数据库基础教程(第2版)》读者勘误
  6. tx2 ubuntu 修改屏幕分辨率
  7. 2019matlab安装
  8. 【Python基础】5-函数编程
  9. python求100被3he7整除_PYTHON练习题测验
  10. 20行Python代码爬取王者荣耀全英雄皮肤