Linux命名管道的创建及应用

目录

一、命名管道的定义即功能

1.1创建命名管道

1.2匿名管道和命名管道的区别

1.3命名管道的打开规则

二、进程间命名管道的创建及使用

2.1Comm.hhp

2.2PipeServer.cc

2.3PipeClient.cc


一、命名管道的定义即功能

管道应用的一个限制就是只能在具有共同祖先(具有亲缘关系)的进程间通信。
如果我们想在不相关的进程之间交换数据,可以使用FIFO文件来做这项工作,它经常被称为命名管道。
命名管道是一种特殊类型的文件。

匿名管道只能通过fork的方式来实现父子两个进程之间的通信,而命名管道则是可以让仁义两个进程间实现通信 ,其底层原理为让两个进程打开同一个文件,一个读一个写从而实现通信的功能,当然此文件并不是真的在磁盘中创建了一个文件而是在内存中开辟了一块缓冲区而已。

而打开同一个文件就需要找到文件,即文件的路径+文件名。而通过文件名加路径的管道就是命名管道。

1.1创建命名管道

命名管道可以从命令行上创建,命令行方法是使用下面这个命令:

$ mkfifo filename

 

命名管道也可以从程序里创建,相关函数有: 

int mkfifo(const char *filename,mode_t mode);

此时就可以看到一个开头为p的管道文件。此时就可以打开两个窗口,一边往里写一边往里读

而系统调用的mkfifo需要两个参数pathname表示要创建文件的文件名,mode则是默认权限。

创建命名管道:
int main(int argc, char *argv[])
{mkfifo("p2", 0644);return 0;
}

1.2匿名管道和命名管道的区别

匿名管道由pipe函数创建并打开。
命名管道由mkfifo函数创建,打开用open。
FIFO(命名管道)与pipe(匿名管道)之间唯一的区别在它们创建与打开的方式不同,一但这些工作完成之后,它们具有相同的语义。

1.3命名管道的打开规则

如果当前打开操作是为读而打开FIFO时
O_NONBLOCK disable:阻塞直到有相应进程为写而打开该FIFO
O_NONBLOCK enable:立刻返回成功
如果当前打开操作是为写而打开FIFO时
O_NONBLOCK disable:阻塞直到有相应进程为读而打开该FIFO
O_NONBLOCK enable:立刻返回失败,错误码为ENXIO

如果想要在代码中删除文件可以调用unlink来进行删除操作。 0返回表示成功,-1表示失败,错误码被设置。

二、进程间命名管道的创建及使用

2.1Comm.hhp

Comm.hpp包含了文件操作所需要的头文件以及常用头文件,包含了Fifo的管道类,可以实现管道的创建及命名,以及在进程结束时及时调用析构函数来对管道进行清理回收。

#ifndef __COMM_HPP__
#define __COMM_HPP__//头文件
#include <cstring>
#include <string>
#include <cerrno>
#include <iostream>
//调用fifo所需的头文件+opean用到的头文件
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>//open
//调用unlink对管道进行析构的头文件
#include <unistd.h>
//define
#define Mode 0666
#define Path "./fifo"
using namespace std;class Fifo
{
public:Fifo(const string &path):_path(path)//创建有名管道{umask(0);int n=mkfifo(_path.c_str(),Mode);if(n==0){cout<<"mkfifo sucess"<<endl;}else{cerr<<"mkfifo failed,errno: "<<errno<<",errstring: "<<strerror(errno)<<endl;}}~Fifo(){int n=unlink(_path.c_str());//删除管道if(n==0){cout<<"remove fifo file "<<_path<<"sucess"<<endl;}else{cerr<<"remove failed,errno: "<<errno<<",errstring: "<<strerror(errno)<<endl;}}
private:string _path;//有名管道的文件路径+文件名
};#endif

2.2PipeServer.cc

服务器端负责创建管道并以读方式open打开:

pipeserver负责创建有名管道fifo并且以读方式进行打开,打开后会发出打开成功的信号,然后等待pipeclient往管道内部写入内容后将其读出以此来达到进程间通信的效果,如果client输入quit则一同退出。

pipeserver就类似于服务器一类的角色,负责创建通信工具和用于接收内容并进行反馈。

#include "Comm.hpp"
#include <unistd.h>int main()
{Fifo fifo(Path);//定义管道文件fifoint rfd=open(Path,O_RDONLY);if(rfd<0){cerr<<"open failed,errno: "<<errno<<",errstring: "<<strerror(errno)<<std::endl;return 1;}//如果我们的写端没有打开,先读端打开,open就会阻塞,直到把写端打开,读open才会返回cout<<"open sucess"<<endl; char buffer[1024];while(true){ssize_t n=read(rfd,buffer,sizeof(buffer)-1);//文件读的时候不需要考虑/0所以sizeof-1if(n>0){buffer[n]=0;//将最后一位变为0cout<<"client say: "<<buffer<<endl;}else if(n==0){cout<<"client quit,me too bye bye"<<std::endl;break;}else{cerr<<"read failed,errno: "<<errno<<",errstring: "<<strerror(errno)<<endl;break;}}close(rfd);return 0;
}

2.3PipeClient.cc

pipeclient则就是供用户进行使用的端口,使用端以写方式打开管道文件,并且负责向管道内部写入数据以及内容,然后由服务器进行读取。

#include "Comm.hpp"int main()
{int wfd=open(Path,O_WRONLY);if(wfd<0){cerr<<"open failed,errno: "<<errno<<",errstring"<<strerror(errno)<<std::endl;return 1;}string inbuffer;while(true){cout<<"Please Enter Your Message#";getline(cin,inbuffer);if(inbuffer=="quit") break;ssize_t n=write(wfd,inbuffer.c_str(),inbuffer.size());if(n<0){cerr<<"write failed,errno: "<<errno<<",errstring: "<<strerror(errno)<<std::endl;break;}}close(wfd);return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/675401.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MySQL之聚合函数与应用

1. 前言 上文我们讲到了单行函数.实际上SQL还有一类叫做聚合函数, 它是对一组数组进行汇总的函数, 输入的是一组数据的集合, 输出的是单个值. 2. 聚合函数 用于处理一组数据, 并对一组数据返回一个值. 有如下几种聚合函数 : AVG(), SUM(), MAX(), MIN(), COUNT(). 3. AVG(…

上位机图像处理和嵌入式模块部署(树莓派4b镜像烧录经验总结)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 陆陆续续也烧录了好多次树莓派的镜像了&#xff0c;这里面有的时候很快&#xff0c;有的时候很慢。特别是烧录慢的时候&#xff0c;也不知道是自己…

基于51单片机的闭环反馈直流电机PWM控制电机转速测量( proteus仿真+程序+设计报告+原理图+讲解视频)

基于51单片机的闭环反馈直流电机PWM控制转速测量( proteus仿真程序设计报告原理图讲解视频&#xff09; 仿真图proteus7.8及以上 程序编译器&#xff1a;keil 4/keil 5 编程语言&#xff1a;C语言 设计编号&#xff1a;S0086 1. 主要功能&#xff1a; 基于51单片机的闭环…

Figma 高效技巧:设计系统中的图标嵌套

Figma 高效技巧&#xff1a;设计系统中的图标嵌套 在设计中&#xff0c;图标起着不可或缺的作用。一套便捷易用的图标嵌套方法可以有效提高设计效率。 分享一下我在图标嵌套上走过的弯路和经验教训。我的图标嵌套可以分三个阶段&#xff1a; 第一阶段&#xff1a;建立图标库 一…

语音识别--光谱门控降噪

⚠申明&#xff1a; 未经许可&#xff0c;禁止以任何形式转载&#xff0c;若要引用&#xff0c;请标注链接地址。 全文共计7267字&#xff0c;阅读大概需要3分钟 &#x1f308;更多学习内容&#xff0c; 欢迎&#x1f44f;关注&#x1f440;【文末】我的个人微信公众号&#xf…

数据结构复习/学习9--二叉树

一、堆与完全二叉树 1.堆的逻辑与物理结构 2.父节点与子节点的下标 3.大小根堆 二、堆的实现&#xff08;大根堆为例&#xff09; 注意事项总结&#xff1a; 注意堆中插入与删除数据的位置和方法与维持大根堆有序时的数据上下调整 三、堆排序 1.排升序建大堆效率高 注意事项…

零基础代码随想录【Day27】|| 39. 组合总和,40.组合总和II, 131.分割回文串

目录 DAY27 39. 组合总和 解题思路&代码 40.组合总和II 解题思路&代码 131.分割回文串 解题思路&代码 DAY27 39. 组合总和 力扣题目链接(opens new window) 给定一个无重复元素的数组 candidates 和一个目标数 target &#xff0c;找出 candidates 中所有…

1天搞定SpringBoot+Vue全栈开发 (7)Axios网络请求

1.Axios的使用 Axios中文文档 | Axios中文网Axios 是一个基于 promise 的网络请求库&#xff0c;可以用于浏览器和 node.jshttps://www.axios-http.cn/ 2.与vue整合 App.vue: <template><div id"app"><Moviev-for"movie in movies":key&qu…

php使用服务器端和客户端加密狗环境部署及使用记录(服务器端windows环境下部署、linux环境宝塔面板部署、客户端部署加密狗)

php使用服务器端和客户端加密狗环境部署及使用记录 ViKey加密狗环境部署1.windows环境下部署开发文档验证代码提示Fatal error: Class COM not found in 2.linux环境下部署&#xff08;宝塔面板&#xff09;开发文档验证代码提示Fatal error: Uncaught Error: Call to undefine…

pwn学习(一)

pwn:二进制漏洞挖掘与利用&#xff08;程序里面的漏洞&#xff09; CTF中的Pwn是仅保留漏洞代码和基本逻辑的二进制程序&#xff0c;选手通过自身对漏洞的熟悉程度来快速的在逆向分析中找到漏洞点&#xff0c;并且结合自身对漏洞利用的熟悉程度来编写EXP脚本&#xff0c;从而获…

动态规划算法:简单多状态问题

例题一 解法&#xff08;动态规划&#xff09;&#xff1a; 算法思路&#xff1a; 1. 状态表⽰&#xff1a; 对于简单的线性 dp &#xff0c;我们可以⽤「经验 题⽬要求」来定义状态表⽰&#xff1a; i. 以某个位置为结尾&#xff0c;巴拉巴拉&#xff1b; ii. 以某个位置为起…

TypeScript学习日志-第二十天(模块解析)

模块解析 一、ES6之前的模块规范 前端模块化规范是有很多的&#xff0c;在es6模块化规范之前分别有一下的模块化规范 一、Commonjs 这是 NodeJs 里面的模块化规范 // 导入 require("xxx"); require("../xxx.js"); // 导出 exports.xxxxxx function() …