Linux命名管道的创建及应用

news2024/11/27 10:33:15

目录

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

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);//定义管道文件fifo

    int 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-1
        if(n>0)
        {
            buffer[n]=0;//将最后一位变为0
            cout<<"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.coloradmin.cn/o/1650592.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[XR806开发板试用] XR806 调用cjson 实现数据序列化

很荣幸获得极术设区提供的这次试用机会&#xff0c;可以接触鸿蒙操作系统。我工作接触最多的是linux 平台的嵌入式ARM平台较多&#xff0c;这次跑了下鸿蒙&#xff0c;也非常有趣。 不过接进年底了&#xff0c;日常大小琐碎事情突然多了起来&#xff0c;测评的比较匆忙&#x…

Java的Fork-Join简单介绍

Java的Fork-Join框架是Java 7引入的一个用于并行处理的轻量级框架&#xff0c;它基于分治策略&#xff08;Divide and Conquer&#xff09;&#xff0c;特别适合于那些可以被分解为多个子任务的任务。Fork-Join框架的核心思想是将一个大任务&#xff08;Task&#xff09;拆分成…

为何大学计算机专业以C语言入门?探究C语言入门的好处

为何大学计算机专业以C语言入门&#xff1f;探究C语言入门的好处 在大学计算机专业中&#xff0c;C语言常作为入门语言&#xff0c;这并非偶然。C语言具有一些独特的优势&#xff0c;使其成为计算机科学教育中的理想选择。本文将探讨为何大学计算机专业选择以C语言入门&#xf…

在Unity中实现分页数据显示和分页控制

参考&#xff1a;用两种简单的方式实现unity的分页效果 using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using UnityEngine.Rendering.VirtualTexturing; using UnityEngine.TerrainUtils;public class PageControll…

简易录制视频做3D高斯

系统环境 ubuntu20 &#xff0c;cuda11.8&#xff0c;anaconda配置好了3D高斯的环境。 具体参考3D高斯环境配置&#xff1a;https://blog.csdn.net/Son_of_the_Bronx/article/details/138527329?spm1001.2014.3001.5501 colmap安装&#xff1a;https://blog.csdn.net/Son_of…

【网络基础2】深入理解TCP协议:协议段、可靠性、各种机制

文章目录 1. TCP协议段格式1.1. 如何解包 / 向上交付1.1.1. 交付1.1.2. 解包 1.2. 如何理解可靠性1.2.1. 确认应答机制&#xff08;ACK&#xff09;1.2.2. 序号 与 确认序号 2. TCP做到全双工的原因2.1. 16位窗口大小2.2. 6个标记位 3. 如何理解连接3.1 连接管理机制3.1.1. 三次…

通俗易懂,Java之Collection接口带你了解集合类型

哈喽&#xff0c;各位小伙伴们&#xff0c;你们好呀&#xff0c;我是喵手。运营社区&#xff1a;C站/掘金/腾讯云&#xff1b;欢迎大家常来逛逛 今天我要给大家分享一些自己日常学习到的一些知识点&#xff0c;并以文字的形式跟大家一起交流&#xff0c;互相学习&#xff0c;一…

风吸式杀虫灯解析

TH-FD2S风吸式杀虫灯是一种创新且环保的害虫控制设备&#xff0c;它结合了太阳能和风力的双重优势&#xff0c;为农业生产、园林绿化以及居民生活等提供了高效且安全的害虫防治方案。 首先&#xff0c;风吸式杀虫灯的工作原理是利用害虫的趋光性&#xff0c;通过特定的光源吸引…

后仿真中的关于延时问题(物理特性角度)

大家都知道&#xff0c;后仿真讲究仿真时序。那么&#xff0c;在网表阶段&#xff0c;接触到后仿延时问题。今天总结一下。 一 延时概念和分类 1.1 分布式延迟&#xff08;Distributed Delays&#xff09; 一般用来指定模块内部信号通过逻辑单元或者线网耗费的时间。 1.2 模…

【嵌入式必读】一文彻底理解PID自整定及PID自整定代码设计

文章目录 1. 前言2. PID简介3. 常用的PID自整定方法3.1 临界度比例法3.2 衰减曲线法 4. 继电反馈整定法原理4.1 继电反馈自整定的基本思想4.2 继电反馈自整定原理 5. 算法设计5.1 振荡的生成5.2 提取出临界周期 T c T_c Tc​和振荡波形幅值 A A A5.3 计算出PID参数 6 原代码6.1…

SQL Server 存储过程中的字符串本身包含单引号的用法

文章目录 引言I 存储过程中的字符串本身包含单引号的用法1.1 问题1.2解决方法引言 使用场景: 字符串类型字段的值比较 I 存储过程中的字符串本身包含单引号的用法 在SQL Server中,单引号用于表示字符串常量。如果你的存储过程中的字符串本身包含单引号,你需要用两个连续的…

PMP的考试费用是多少啊?大概需要多少钱?

如何以最低的经济成本取得PMP证书呢&#xff1f;PMP的认证考试费用包括考试报名费、学习备考费用和续证费用三个部分。 考试报名费用 PMP考试费用&#xff1a;PMP普通申请者初次考试费用为固定3900元人民币&#xff0c;补考&#xff08;重考&#xff09;费用为2500元人民币。退…

springboot 获取maven打包时间

springboot 获取maven打包时间 pom <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.1.13.RELEASE</version><relativePath /> <!-- lookup parent…

【Linux系列】file命令

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

C语言常见的动态内存错误及几个经典笔试题以及c/c++内存开辟空间等的介绍

文章目录 前言一、常见的动态内存错误1. 对NULL指针的解引用操作2. 对动态开辟空间的越界访问3. 对非动态开辟内存使用free()4. 使用free释放一块动态开辟内存的一部分5. 对同一块动态内存多次释放6. 动态开辟内存忘记释放&#xff08;内存泄漏&#xff09; 二、几个经典笔试题…

【busybox记录】【shell指令】shuf

目录 内容来源&#xff1a; 【GUN】【shuf】指令介绍 【busybox】【shuf】指令介绍 【linux】【shuf】指令介绍 使用示例&#xff1a; 打乱内容 - 默认输出 打乱内容 - 最多输出n行 打乱内容 - 将输出写入文件 打乱内容 - 重复输出 打乱内容 - 打乱本条指令的参数 打…

Concise CoT(CCoT)提示词工程

原文地址&#xff1a;concise-chain-of-thought-ccot-prompting 2024 年 1 月 24 日 传统的 CoT 是以增加输出令牌使用为代价的&#xff0c;CCoT 提示是一种提示工程技术&#xff0c;旨在减少 LLM 响应的冗长和推理时间。 基于LLMs的生成式人工智能应用程序必须使用多管齐下的方…

静态分配IP,解决本地连接不上Linux虚拟机的问题

在Window环境下&#xff0c;使用远程终端工具连接不了VMware搭建的Linux虚拟机&#xff08;CentOS 7&#xff09;&#xff0c;并且在命令行ping不通该Linux虚拟机的IP地址。下面通过配置网关解决本地与Linux虚拟机连接问题&#xff1a; 1 查看虚拟机网关地址 在VMware虚拟机上…

文本清洁器:如何一键批量删除空格,让内容更整洁的技巧

在日常工作和学习中&#xff0c;我们经常需要处理大量的文本内容。而文本中多余的空格往往会让内容显得杂乱无章&#xff0c;影响阅读体验。为了解决这个问题&#xff0c;我们可以使用办公提效工具来一键批量删除空格&#xff0c;让内容更加整洁易读。 一、为什么需要批量删除空…

js宏任务微任务输出解析

第一种情况 setTimeout(function () {console.log(setTimeout 1) //11 宏任务new Promise(function (resolve) {console.log(promise 1) //12 同步函数resolve()}).then(function () {console.log(promise then) //13 微任务})})async function async1() {console.log(async1 s…