进程间通信之利用命名管道进行通信

文章目录

  • 什么是命名管道
  • 命名管道的作用有什么
  • 命名管道的特点和用法是什么
  • 命名管道与匿名管道有什么区别
    • 匿名管道相较于命名管道的局限性
  • 命名管道如何使用
  • 代码

什么是命名管道

命名管道(Named Pipe),也被称为FIFO(First In, First Out),是一种在Unix和Unix-like操作系统中用于进程间通信的特殊文件类型。它允许不相关的进程通过文件系统中的路径名进行通信。

命名管道的作用有什么

命名管道(Named Pipe)是一种在Unix和Unix-like系统中用于进程间通信的特殊文件类型。它的作用主要体现在以下几个方面:

进程间通信: 命名管道提供了一种进程间通信的方式。不同的进程可以通过共享同一个命名管道文件进行通信,其中一个进程将数据写入管道,而另一个进程从管道中读取数据。这样,进程之间可以实现数据的交换和共享。

无关进程通信: 与匿名管道不同,命名管道可以用于无关的进程之间通信。因为命名管道在文件系统中有一个路径名,进程可以通过路径名来打开和访问它,而不需要共享相同的地址空间或具有亲缘关系。

独立于进程生命周期: 命名管道是持久的,它存在于文件系统中,不受创建它的进程的生命周期限制。这意味着即使创建命名管道的进程结束,其他进程仍然可以使用相同的管道进行通信。

阻塞式通信: 命名管道是阻塞的,即写入端会等待读取端准备好接收数据,反之亦然。这样可以协调进程之间的通信,确保数据的正确传输。

常用于Shell编程: 在Shell编程中,命名管道常用于将一个命令的输出传递给另一个命令,实现管道传输的同时也可以用于进程间通信。

总体而言,命名管道提供了一种方便、灵活且持久的进程间通信机制,适用于各种需要数据交换的场景。

命名管道的特点和用法是什么

文件系统中的路径名: 命名管道在文件系统中有一个路径名,类似于普通文件。进程可以通过打开这个路径名的方式来访问命名管道。

独立的进程通信: 不同进程可以通过共享同一个命名管道文件来进行通信。这使得命名管道成为不同进程之间进行进程间通信的有效手段。

创建和删除: 命名管道可以使用 mkfifo 函数来创建。创建后,它就成为文件系统中的一个特殊文件。当通信结束时,可以使用 unlink 函数删除命名管道。

读写操作: 进程可以像普通文件一样使用文件描述符对命名管道进行读取和写入操作,实现进程间的数据传输

命名管道与匿名管道有什么区别

命名管道(Named Pipe)和匿名管道(Anonymous Pipe)是两种不同类型的管道,它们在创建、使用和生命周期等方面有一些关键区别。

命名管道:

创建: 命名管道在文件系统中有一个路径名,可以通过 mkfifo 函数创建。它是一个具有持久性的文件,不依赖于创建它的进程的生命周期。
路径名: 命名管道有一个在文件系统中的路径名,因此可以被不同的进程通过路径名来访问。
无关进程通信: 不相关的进程可以通过共享同一个路径名的命名管道进行通信。
使用: 通过文件描述符进行读写操作,可以使用标准的文件I/O函数。
生命周期: 命名管道存在于文件系统中,直到显式删除。
匿名管道:

创建: 匿名管道是由 pipe 系统调用创建的,没有在文件系统中的路径名。它是一种临时的、仅存在于相关进程之间的通信机制。
路径名: 不存在路径名,只能在创建它的进程及其相关子进程之间使用。
有关进程通信: 主要用于有关系(亲缘关系)的父子进程之间通信。
使用: 通过文件描述符进行读写操作,可以使用标准的文件I/O函数。
生命周期: 随着创建它的进程或相关子进程的终止而结束。
综上所述,主要区别在于命名管道是具有路径名的、持久的文件,可以被不相关的进程使用;而匿名管道是临时的、只存在于相关进程之间的通信机制,主要用于父子进程之间通信。选择使用哪种管道取决于具体的应用场景和需求。

匿名管道相较于命名管道的局限性

首先我们可以先看一下匿名管道的代码

#include <iostream>
#include <string>
#include <unistd.h>
#include <string.h>
#include <string>
#include <cstdio>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
using namespace std;
#define N 2
const int NUM = 1024;
void Write(int n)
{string s = "hello,I am chile";pid_t self = getpid();char buffer[NUM]; // 缓冲区int number = 0;while (true){buffer[0] = 0; // 字符串清空snprintf(buffer, sizeof(buffer), "%s-%d-%d", s.c_str(), self, number++);// cout << buffer << endl;write(n, buffer, strlen(buffer));sleep(1);}
}
void Read(int rfd)
{char buffer[NUM];while (true){buffer[0] = 0;ssize_t n = read(rfd, buffer, sizeof(buffer));if (n > 0){buffer[n] = 0;cout << "father get a message[" << getpid() << "]# " << buffer << endl;}}
}int main()
{int pipefd[N] = {0};int n = pipe(pipefd);if (n < 0)return 1;pid_t id = fork();if (id < 0)return 2;if (id == 0){close(pipefd[0]);Write(pipefd[1]);close(pipefd[1]);exit(0);}close(pipefd[1]);Read(pipefd[0]);pid_t rid = waitpid(id, NULL, 0);if (rid < 0){return 3;}close(pipefd[0]);return 0;
}

从上面代码我们可以清晰的感知到匿名管道只适用与具有亲缘关系的进程之间的通信但是我们在实际开发环境中更多的进程是不具备亲缘关系的因此匿名管道就非常的局限了。我们看一下匿名管道的最终实现的效果图
在这里插入图片描述

命名管道如何使用

我们来看一下命名管道的使用效果图
在这里插入图片描述
在这张图我们可以清楚的看到右边输入左边输出达到了我们想要的无亲缘关系的进程的通信

代码

1.comm.hpp文件

#pragma once#include <iostream>
#include <string>
#include <cerrno>
#include <cstring>
#include <cstdlib>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>#define FIFO_FILE "./myfifo"
#define MODE 0664
enum
{FIFO_CREATE_ERR = 1,FIFO_DELETE_ERR,FIFO_OPEN_ERR
};class Init
{
public:Init(){int n = mkfifo(FIFO_FILE, MODE);if (n == -1){perror("mkfifo");exit(FIFO_CREATE_ERR);}}~Init(){int m = unlink(FIFO_FILE);if (m == -1){perror("unlink");exit(FIFO_DELETE_ERR);}}
};
  1. server.cpp文件代码
#include "comm.hpp"
#include <iostream>
using namespace std;
int main()
{Init init;int fd = open(FIFO_FILE, O_RDONLY);if (fd < 0){exit(FIFO_OPEN_ERR);}while (true){char buffer[1024];int len = read(fd, buffer, sizeof(buffer));if (len < 0){break;}else if (len > 0){buffer[len] = 0;cout << "client say#" << buffer << endl;}else if (len == 0){break;}}close(fd);return 0;
}
  1. client.cpp的代码
#include "comm.hpp"
#include <iostream>
using namespace std;
int main()
{int fd = open(FIFO_FILE, O_WRONLY);if (fd == -1){perror("open");exit(FIFO_OPEN_ERR);}else{cout << "client open file done" << endl;while (1){cout << "Please Enter@ ";string a;getline(cin, a);write(fd, a.c_str(), a.size());}}close(fd);return 0;
}

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

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

相关文章

剪映可以压缩视频大小吗?只需这样操作~

剪映是一款全能易用的视频剪辑软件&#xff0c;支持变速、多样滤镜等功能&#xff0c;当然&#xff0c;通过它也可以起到压缩视频大小的作用&#xff0c;如果你还不知道怎么压缩&#xff0c;不妨继续了解下去吧。 一、手机端压缩方法 1、在剪映APP中打开需要压缩的视频&#x…

centos7 arm服务器编译安装PaddlePaddle

前言 随着国产服务器发展&#xff0c;部署项目需要用在国产服务器上&#xff0c;官方教程里面很多没有讲解到&#xff0c;安装过程中出现了各种各样的问题&#xff0c;以下是对官方教程的补充&#xff0c;有什么问题&#xff0c;欢迎指正&#xff01; 一、环境准备 gcc: 8.2版…

升级8.0:民生手机银行的“内容解法”

数字化浪潮&#xff0c;滚滚来袭。 随着数字中国建设的持续推进&#xff0c;数字经济正在蓬勃发展。中商产业研究院分析师预测&#xff0c;2023年中国数字经济市场规模将增长至56.7万亿元&#xff0c;占GDP的比重将达到43.5%。 在此浪潮下&#xff0c;数字化的触角蔓延到各行…

Docker五部曲之五:通过Docker和GitHub Action搭建个人CICD项目

文章目录 项目介绍Dockerfile解析compose.yml解析Nginx反向代理到容器以及SSL证书设置MySQL的准备工作Spring和环境变量的交互 GitHub Action解析项目测试结语 项目介绍 该项目是一个入门CICD-Demo&#xff0c;它由以下几部分组成&#xff1a; Dockerfile&#xff1a;用于构建…

【图解数据结构】深度解析时间复杂度与空间复杂度的典型问题

&#x1f308;个人主页&#xff1a;聆风吟 &#x1f525;系列专栏&#xff1a;图解数据结构、算法模板 &#x1f516;少年有梦不应止于心动&#xff0c;更要付诸行动。 文章目录 一. ⛳️上期回顾二. ⛳️常见时间复杂度计算举例1️⃣实例一2️⃣实例二3️⃣实例三4️⃣实例四5…

电子词典Qt版

1. 服务端 词典数据&#xff0c;数据库路径&#xff1a;E:\peixunQianrushi\Qt\course\course10\cidain_shuju cidian_server widget.h #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QDebug> #include <QTcpServer> #include <QTcpSoc…

力扣每日一练(24-1-18)

经验一&#xff1a;不要把问题想复杂 Python&#xff1a; min_price float(inf)max_profit 0for price in prices:min_price min(min_price, price)max_profit max(max_profit, price - min_price)return max_profit C#&#xff1a; public int MaxProfit(int[] prices) {i…

npm run dev 启动vue的时候指定端口

使用的是 Vue CLI 来创建和管理 Vue 项目&#xff0c; 可以通过设置 --port 参数来指定启动的端口号。以下是具体的步骤&#xff1a; 打开命令行终端 进入您的 Vue 项目目录 运行以下命令&#xff0c;通过 --port 参数指定端口号&#xff08;例如&#xff0c;这里设置端口号…

基于YOLOv8深度学习的100种中草药智能识别系统【python源码+Pyqt5界面+数据集+训练代码】目标检测、深度学习实战

《博主简介》 小伙伴们好&#xff0c;我是阿旭。专注于人工智能、AIGC、python、计算机视觉相关分享研究。 ✌更多学习资源&#xff0c;可关注公-仲-hao:【阿旭算法与机器学习】&#xff0c;共同学习交流~ &#x1f44d;感谢小伙伴们点赞、关注&#xff01; 《------往期经典推…

计算机网络-ACL实验

一、NAT实验配置 NAT实验配置 通过基本ACL匹配VLAN 10网段&#xff0c;然后在出口设备NAT转换只要匹配到VLAN10地址则进行转换。 核心交换机 # 配置VLAN和默认路由&#xff0c;配置Trunk和Access接口 interface Vlanif10ip address 192.168.10.254 255.255.255.0 # interface V…

【JVM】内存结构

Java 虚拟机的内存空间 Java 虚拟机的内存空间分为 5 个部分&#xff1a; 程序计数器 Java 虚拟机栈 本地方法栈 堆 方法区 JDK 1.8 同 JDK 1.7 比&#xff0c;最大的差别就是&#xff1a;元数据区取代了永久代。元空间的本质和永久代类似&#xff0c;都是对 JVM 规范中方法区…

Visual Studio离线版本下载安装

Visual Studio离线版本下载安装 一&#xff0c;版本下载 url&#xff1a; Visual Studio官网 下载新版本&#xff1a; 下载老版本&#xff1a; 需要将官网页面拉在最下方&#xff0c;点击较早的下载&#xff0c;选择老版本进行下载 下载后的可执行文件&#xff1a; 二&am…