Linux--进程间通信之命名管道

在这里插入图片描述


目录

  • 前言
  • 概念
    • 命名管道的创建
    • 命名管道特性
  • 命名管道通信
    • 建立连接
    • 资源处理
  • Client && Server通信
  • 总结


前言

上一篇文章介绍匿名管道的进程间通信只适合在具有血缘关系的进程间进行通信,但是如果我们想让两个不相关的进程实现通信,使用匿名管道显然已经不太合适,这时候就可以使用另一种方案来实现让不同的进程间进行通信,这就是这篇文章要介绍的——命名管道。

概念

命名管道(Named Pipes),也称为FIFO(First In, First Out),是一种进程间通信的机制。它允许不相关的进程在一个系统中通过文件系统来进行通信。

在这里插入图片描述

命名管道的创建

命名管道的创建可以使用命令行工具(如mkfifo命令)或者在编程语言中的调用系统调用接口(如mkfifo函数)来创建命名管道。与匿名管道一样,命名管道也存在于内存中,命名管道是一种特殊类型的文件,类似于普通管道。数据通过命名管道传输时不会写入磁盘,而是在内存中进行传递。命名管道允许多个进程通过使用相同的管道名称进行通信,而不仅仅是两个进程之间的通信。与普通管道一样,命名管道中的数据也是临时存储在内存中的。

在命令行中可以直接使用命令mkfifo [pipename]来创建我们需要的命名管道文件。

在这里插入图片描述
或者可以使用系统调用接口int mkfifo(const char *pathname, mode_t mode)来创建所需要的管道文件,如下代码。

#include <iostream>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <errno.h>
int main()
{umask(0);int ret = mkfifo("namepipe", 0666);if (ret == -1){std::cout << errno << " : " << strerror(errno) << std::endl;}else{std::cout << "create success!" << std::endl;}return 0;
}

因为命名管道在创建后也是一种文件,所以在使用mkfifo系统调用接口时需要注意给定权限。文件最终的权限为mode & ~umask,因此在创建之前我们可以先将umask置0。另外使用mkfifo创建命名管道如果成功则返回0,失败返回-1并设置错误码,所以在创建时可以接收返回值做差错处理。

在这里插入图片描述

命名管道特性

命名管道与匿名管道类似,允许两个或多个进程通过读取和写入管道文件来进行通信。一个进程可以将数据写入管道,而另一个进程可以从管道中读取这些数据。也是一种半双工通信,数据按照写入的顺序以字节流的形式读取。如果没有进程打开管道的另一端进行读取,写入进程可能会被阻塞,直到有其他进程来读取数据。同样,如果没有进程写入管道,尝试读取管道的进程也会被阻塞。命名管道的声明周期是持久的,直到被明确删除为止。命名管道不适用于网络通信,它仅用于本地进程之间的通信。

命名管道通信

建立连接

使用命名管道通信前提还是让相互独立的进程能看到同一份资源,对同一份资源进行操作。所以在命名管道通信之前要先建立链接,建立链接第一步就是创建命名管道,然后在打开命名管道。为了能让不同进程能对同一个管道文件进行操作,因此应该约定好让一个进程在某个路径下创建好一个命名管道,其余进程就可以直接打开这个路径下的命名管道,这样就可以让几个进程先建立好链接。

资源处理

因为命名管道生命周期不随进程,一旦创建后如果不是人为删除就会一直存在,因此在通信完毕之后除了关闭相应的文件描述符,还需要将没有用的管道文件进行删除。在命令行上可以使用rm命令,在程序里面可以使用unlink系统调用接口函数进行删除。

  • unlink是一个系统调用函数,用于删除文件系统中的文件。它可以删除普通文件、符号链接和命名管道等文件类型。
  • 当你调用unlink函数来删除一个文件时,它会从文件系统中删除该文件的目录项(directory entry),并释放该文件占用的磁盘空间。文件的实际数据在删除后将不再可用。但是,如果有其他进程仍然打开了该文件,那么文件仍然存在,只是无法通过文件名访问。只有当所有对该文件的打开引用都关闭后,文件空间才会被完全释放。
  • 需要注意的是,unlink函数只删除文件的目录项,而不会对打开的文件描述符产生影响。这意味着,即使使用unlink删除了文件,仍然可以通过已打开的文件描述符继续访问和操作文件的内容,直到关闭文件描述符。使用unlink函数删除文件是一个不可逆的操作,请谨慎使用,确保你真正想要删除的是该文件。

在这里插入图片描述

Client && Server通信

万事俱备,只欠东风。在有了上述的内容储备后,就可以简单的写一份Client和Server两进程的简单通信了。

可以设计一个这样的程序,让Server进程创建一个命名管道,并以只读的方式打开,然后循环的读取内容。让Client进程直接以只写的方式打开命名管道,循环的将数据写入到命名管道中。当Server进程检测到Client进程退出时,Server进程关闭相应的文件描述符并删除命名管道。为了更好的测试,可以将程序设计为交互式的,当我们输入quit时Client结束写入跳出循环然后关闭文件描述符退出,Server进程在检测到Client进程退出后,再将管道里数据读取完毕后也跳出循环结束读取,关闭文件描述符后删除命名管道。这样我们就可以写出如下代码:

//comm.hpp
#include <iostream>
#include <string>
#include <sys/types.h>
#include <sys/stat.h>
#include <cstring>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#define NUM 1024mode_t mode = 0666;
const std::string fileName = "./fifo";
//Server.cc
#include "comm.hpp"int main()
{umask(0);// 创建命名管道int ret = mkfifo(fileName.c_str(), mode);if (ret == -1){std::cout << errno << " : " << strerror(errno) << std::endl;exit(-1);}std::cout << "create namepipe success" << std::endl;// 打开命名管道int fd = open(fileName.c_str(), O_RDONLY);if (fd < 0){std::cout << errno << " : " << strerror(errno) << std::endl;exit(-1);}// 开始写入while (1){char buffer[NUM];int n = read(fd, buffer, sizeof(buffer));if (n > 0){buffer[n] = '\0';std::cout << "client # " << buffer << std::endl;}else if (n == 0){std::cout << "communication finish" << std::endl;break;}else{std::cout << errno << " : " << strerror(errno) << std::endl;break;}}close(fd);unlink(fileName.c_str());return 0;
}
//Client.cc
#include "comm.hpp"
#include <iostream>
bool check(const char* s)
{std::string str;while(*s != '\n'){str += *s;s++;}return str != "quit";
}int main()
{// 打开命名管道int fd = open(fileName.c_str(), O_WRONLY);if (fd < 0){std::cout << errno << " : " << strerror(errno) << std::endl;exit(-1);}// 写入内容char buffer[NUM];std::cout << "Input : ";char* ret = fgets(buffer, NUM, stdin);while (check(ret)){buffer[strlen(buffer) - 1] = '\0';write(fd, buffer, strlen(buffer));std::cout << "Input : ";ret = fgets(buffer, NUM, stdin);}close(fd);return 0;
}

在这里插入图片描述

总结

管道是一种在进程间进行通信的机制。它可以用于在一个进程中将输出连接到另一个进程的输入,从而实现它们之间的数据传输。无论是命名管道还是匿名管道,他们都属于管道通信并且都具有如下的几种特性:

  • 单向通信:管道是单向的,分为读端和写端。写入端将数据写入管道,读取端从管道中读取数据。数据在管道中按先进先出(FIFO)的顺序传输。

  • 匿名管道和命名管道:管道可以是匿名的,也可以是命名的。匿名管道只能在具有亲缘关系的进程之间使用,而命名管道可以用于无关进程之间的通信。

  • 进程间通信:管道通信通常用于父子进程或者兄弟进程之间的通信。父进程创建管道,并将其的写端传递给子进程,子进程通过读取管道来接收父进程发送的数据。

  • 有限的容量:管道有一个有限的容量,通常是操作系统内核中的一个缓冲区。一旦管道被填满,进一步的写入操作将会阻塞,直到有足够的空间来容纳数据。

  • 阻塞和非阻塞操作:管道的读取和写入操作可以是阻塞的或非阻塞的。阻塞操作将会一直等待直到数据可用或空间可用,而非阻塞操作将立即返回,无论是否有数据可用或空间可用。

  • 临时性:管道中的数据是临时的,一旦相关进程关闭了管道的读写端,管道中的数据将被销毁,无法再被读取。这是因为管道的数据存储在内核的缓冲区中,而不是保存在文件系统中。

管道是一种简单而有效的进程间通信机制,但它也有一些限制。例如,它只支持单向通信,数据传输是基于字节流而不是消息的,且容量有限。如果需要更复杂的通信需求,可以考虑其他的进程间通信方式,如命名管道、消息队列、共享内存等。

最后,码文不易,如果觉得文章对你有帮助的话,就点一个👍呗。

在这里插入图片描述

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

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

相关文章

Kafka:安装与简单使用

文章目录 下载安装windows安装目录结构启动服务器创建主题发送一些消息启动消费者设置多代理集群常见问题 工具kafka tool 常用指令topic查看topic删除topic 常见问题参考文献 下载安装 下载地址&#xff1a;kafka-download windows安装 下载完后&#xff0c;找一个目录解压…

notepad++配置python2环境

&#xff08;1&#xff09;python2版本下载&#xff1a;Index of /ftp/python/2.7.8/https://www.python.org/ftp/python/2.7.8/ &#xff08;2&#xff09; 配置notepad环境 1.打开Notepad&#xff0c;点击“插件”-“插件管理器”&#xff0c;在“可用”选项卡中&#xff0c…

前言技术 VScode + 其他插件-2

一、扩展插件 1.1 chinese 作用&#xff1a;使得软件变成中文显示 1.2 prettier 作用&#xff1a;格式化代码 需要多重配置&#xff1b;看视频 第一步&#xff1a;安装 第二步&#xff1a;软件设置 第三步&#xff1a;查询 save , 修改保存时自动对齐格式&#xff0c;打✔…

【软考】系统集成项目管理工程师(五)项目立项管理【5分】

一、 项目建议书 1、定义 项目建议书又称为立项申请&#xff1b;建设单位向上级主管部门提交项目申请时所必须的文件&#xff0c;是对拟建项目提出的框架性的总体设想&#xff1b;是项目发展周期的初始阶段&#xff0c;是国家或上级主管部门选择项目的依据&#xff0c;也是可行…

WordPress外贸建站Astra免费版教程指南(2023)

在WordPress的外贸建站主题中&#xff0c;有许多备受欢迎的主题&#xff0c;如AAvada、Astra、Hello、Kadence等最佳WordPress外贸主题&#xff0c;它们都能满足建站需求并在市场上广受认可。然而&#xff0c;今天我要介绍的是一个不断颠覆建站人员思维的黑马——Astra主题。 …

Hudi第二章:集成Spark

系列文章目录 Hudi第一章&#xff1a;编译安装 Hudi第二章&#xff1a;集成Spark 文章目录 系列文章目录前言一、安装Spark1、安装Spark2.安装hive 二、spark-shell1.启动命令2.插入数据3.查询数据1.转换DF2.查询 3.更新4.时间旅行5.增量查询6.指定时间点查询7.删除数据1.获取…

linux Mysql 8.0.16 安装搭建

文章目录 Mysql 搭建一、安装包下载二、创建用户组用户和修改权限三、配置my.cnf Mysql 搭建 一、安装包下载 mysql 下载地址&#xff1a;https://downloads.mysql.com/archives/community/ 这里有所有的mysql的版本&#xff0c;下载自己需要的版本&#xff0c;我们这里下载 …

视频高效剪辑,批量调整视频速度,让视频更加精彩

你是否曾经需要调整多个视频的速度&#xff0c;但却苦于手动操作效率低下&#xff1f;如果你也遇到了这样的问题&#xff0c;那么是时候采取行动&#xff0c;使用一款高效易用的视频处理工具了。 首先&#xff0c;我们要进入好简单批量智剪&#xff0c;并在板块栏里选择“任务…

搭建自己的搜索引擎之五

一、前言 接上文 搭建自己的搜索引擎之四&#xff0c;下面继续介绍茴香豆茴字的另外两种写法。 二、Jest Jest是ES的Java Http Rest客户端&#xff0c;它主要是为了弥补以前ES自有API缺少HttpRest接口客户端的不足&#xff0c;但因为现在ES官方已经提供了RestClient ,该项目已…

cJSON.c 在mfc中编译失败报 lnk2005错误

问题一、在MFC工程中导入cJson.c 编译时报以下错误&#xff1a; 严重性 代码 说明 项目 文件 行 禁止显示状态 错误 C1853 “x64\Release\xxx.pch”预编译头文件来自编译器的早期版本&#xff0c;或者预编译头为 C 而在 C 中使用它(或相反) xxx …

【广州华锐互动】鱼类授精繁殖VR虚拟仿真实训系统

随着科技的不断发展&#xff0c;虚拟现实技术在各个领域的应用越来越广泛。在养殖业中&#xff0c;VR技术可以帮助养殖户进行家鱼授精实操演练&#xff0c;提高养殖效率和繁殖成功率。本文将介绍利用VR开展家鱼授精实操演练的方法和应用。 首先&#xff0c;我们需要了解家鱼授精…

WorkPlus私有化部署IM即时通讯平台,构建高效安全的局域网办公环境

随着数字化转型的加速&#xff0c;政府机构与企业对高效、安全的即时通讯和协作工具的需求日益增长。企业微信和钉钉作为当前市场上较为常见的通讯工具&#xff0c;虽然在一定程度上满足了企业内部协作的需求&#xff0c;但仍存在一些问题&#xff0c;如数据安全性、私有化部署…

N 皇后问题

N 皇后问题研究的是如何将 N 个皇后放置在 N x N 的棋牌上&#xff0c;并且使皇后彼此之间不能相互攻击。 国际象棋的规则&#xff0c;皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子 解决思路是&#xff1a;剪枝 回溯方法 解决问题 (1).使用二维数组创建棋牌格子 g…

C++与QML交互总结二

目录 1.CPP调用QML 1.1 QMetaObject::invokeMethod调用 1.2 CPP中的信号绑定qml中的槽 2.QML调用CPP 2.1 QML单实例注册 2.2 将类对象注册到QML的上下文中 2.3 QML信号调用CPP槽 3.QML中注入一个cpp实例 3.1qmlRegisterType 3.2QML_ELEMENT 4.附加属性: QML_ATTACHE…

面试题:说一下SpringBoot的自动配置原理

文章目录 引言工作原理剖析EnableAutoConfiguration自动配置生效总结 引言 不论在工作中&#xff0c;亦或是求职面试&#xff0c;Spring Boot已经成为我们必知必会的技能项。除了某些老旧的政府项目或金融项目持有观望态度外&#xff0c;如今的各行各业都在飞速的拥抱这个已经…

c==ubuntu+vscode debug redis7源码

新建.vscode文件夹&#xff0c;创建launch.json和tasks.json {"version": "0.2.0","configurations": [{"name": "C/C Launch","type": "cppdbg","request": "launch","prog…

Flink CDC MySQL同步MySQL错误记录

1、启动 Flink SQL [appuserwhtpjfscpt01 flink-1.17.1]$ bin/sql-client.sh2、新建源表 问题1&#xff1a;Encountered “(” 处理方法&#xff1a;去掉int(11)&#xff0c;改为int Flink SQL> CREATE TABLE t_user ( > uid int(11) NOT NULL AUTO_INCREMENT COMME…

1 论文笔记:Efficient Trajectory Similarity Computation with ContrastiveLearning

2022CIKM 1 intro 1.1 背景 轨迹相似度计算是轨迹分析任务&#xff08;相似子轨迹搜索、轨迹预测和轨迹聚类&#xff09;最基础的组件之一现有的关于轨迹相似度计算的研究主要可以分为两大类&#xff1a; 传统方法 DTW、EDR、EDwP等二次计算复杂度O(n^2)缺乏稳健性 会受到非…

【Linux】进程控制基础知识

目录 一&#xff0c;fack回顾 二&#xff0c;进程终止 1.进程终止&#xff0c;操作系统做了什么&#xff1f; 2.进程终止&#xff0c;常见的方式 1.main函数的&#xff0c;return 返回码 2. exit()函数 三&#xff0c;进程等待 1. 回收进程方法 &#xff08;1. wait…

Node.js 学习笔记

小插件Template String Converter 当输入${}时&#xff0c;自动为其加上 反引号 一、node入门 node.js是什么 node的作用 开发服务器应用 开发工具类应用 开发桌面端应用 1.命令行工具 命令的结构 常用命令 切换到D盘——D: 查看D盘目录——dir 切换工作目录——c…