当前位置: 首页 > news >正文

Linux下进程间的通信--管道

关于进程间的通信

Linux进程间通信(Inter-Process Communication,IPC)是指在多个进程之间传输数据或信号的一些方法。由于Linux中的进程有各自独立的地址空间,因此它们不能直接访问对方的内存。为了实现进程间的通信,Linux提供了多种机制:管道,信号,消息队列,共享内存,网络

Linux下的进程通信手段基本上是从Unix平台上继承而来的

进程间通讯分为单个计算机的进程间通讯和局域网的进程间通讯

管道

管道简介:

管道是一种最基本的IPC机制,它允许一个进程的输出成为另一个进程的输入。管道是半双工的,数据只能向一个方向流动

管道的本质:是操作系统内核提供的一种进程间通信机制,它通过内核缓冲区和文件描述符来实现进程间的数据交换和同步

管道分为无名管道与有名管道

一.无名管道

无名管道的特点:

无名管道只能实现单向通信,数据只能从一端流向另一端

无名管道通常用于父子进程之间的通信,因为它们需要在创建时就确定通信的两端

无名管道没有名字,它们在文件系统中不可见,仅在创建它们的进程及其子进程的生命周期内存在。

无名管道将读端与写端抽象成两个文件进行操作,在无名管道创建成功之后,则会返回将读端与写端的文件描述符存入数组

创建无名管道

pipe()函数

函数描述:pipe()创建了一个管道,这是一种单向数据通道,可用于进程间通信。数组 pipefd 用于返回指向管道两端的两个文件描述符。pipefd[0]`指向管道的读端,pipefd[1] 指向管道的写端。写入管道写端的数据将由内核缓冲,直到从管道读端读取。

函数头文件
#include <unistd.h>   功能
管道创建之后,内核会将文件描述符存储到数组    函数原型
int pipe(int pipefd[2]);函数参数
pipefd:用于存储无名管道读端与写端的文件描述符的数组
pipefd[0]:读端文件描述符
pipefd[1]:写端文件描述符    函数返回值:
成功:0
失败:-1,设置 errno,同时将pipefd保持不变

 示例代码:

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>int main()
{int pipefd[2];int num=pipe(pipefd);if(num == -1){perror("pipe\n");exit(EXIT_FAILURE);}pid_t pid = fork(); // 创建子进程if (pid == -1){perror("fork failed");return 1;}else if (pid == 0){close(pipefd[1]);char buffer[64];size_t rbytes = read(pipefd[0],buffer,sizeof(buffer));if(rbytes == -1){perror("read fail\n");close(pipefd[0]);}else{printf("read : %s\n",buffer);close(pipefd[0]);}}else{close(pipefd[0]);char buf[128]={0};printf("please to input information\n");fgets(buf,sizeof(buf),stdin);buf[strlen(buf)-1]='\0';size_t wbytes = write(pipefd[1],buf,sizeof(buf));if(wbytes==-1){perror("write fail\n");close(pipefd[1]);}else{printf("wbytes = %ld\n",wbytes);close(pipefd[1]);}}waitpid(-1,NULL,0);return 0;
}

 代码解读:

使用pipe函数创建一个无名管道,并将文件描述符数组pipefd的两个元素分别设置为管道的读端和写端。如果创建失败,打印错误信息并退出

调用fork函数创建子进程。如果fork失败,打印错误信息并返回1。

如果pid为0,说明当前是子进程。关闭管道的写端文件描述符。

定义一个字符数组buffer,用于存储从管道读取的数据。

从管道的读端读取数据到buffer。如果读取失败,打印错误信息并关闭读端文件描述符。如果读取成功,打印读取的内容并关闭读端文件描述符。

如果pid不为0,说明当前是父进程。关闭管道的读端文件描述符。

定义一个字符数组buf,用于存储用户输入的数据。

将用户输入的数据写入管道的写端。如果写入失败,打印错误信息并关闭写端文件描述符。如果写入成功,打印写入的字节数并关闭写端文件描述符。

调用waitpid函数等待子进程结束。-1表示等待任意子进程,NULL表示不需要子进程的终止状态,0表示不设置任何选项。

二.有名管道

有名管道的特点:

有名管道在文件系统中以文件的形式存在,但不占用磁盘空间,即使创建它的进程已经退出,有名管道仍然存在,直到被显式删除。

有名管道允许任何知道管道名称的进程进行通信

有名管道提供了一种同步机制,写入操作在管道有足够空间时才会成功,读取操作在管道中有数据时才会成功

创建有名管道

mkfifo命令

mkfifo [选项]... 名字
  • -m 或 --mode=模式:设置创建的有名管道的权限。如果不设置,将使用默认的权限(通常是 0666,即允许所有用户读写)。
  • -p 或 --fifo=路径:指定有名管道的路径。如果路径不存在,mkfifo 会创建它。

mkfifo()系统调用

函数描述:

mkfifo()创建一个名为pathname的FIFO特殊文件。mode指定FIFO的权限。它由进程的umask以通常的方式修改:创建的文件的权限是(mode & ~umask)。

FIFO特殊文件类似于管道,只是其创建方式不同。通过调用mkfifo()将FIFO特殊文件输入到文件系统中,而不是作为匿名通信通道。

一旦你以这种方式创建了一个FIFO特殊文件,任何进程都可以打开它进行读写,就像普通文件一样。但是,在您可以对其进行任何输入或输出操作之前,它必须同时在两端打开。为读打开FIFO通常会阻塞,直到其他进程为写打开相同的FIFO,反之亦然。

函数头文件
#include <sys/types.h>
#include <sys/stat.h>函数原型:
int mkfifo(const char *pathname, mode_t mode);函数参数:
pathname:有名管道路径名
mode:有名管道文件访问权限, 常用0644函数返回值:
成功:返回0
失败:返回-1,并设置errno

示例代码:

进程A:

#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <fcntl.h>
#define PATH "/home/linux/namepipe"
int main()
{int fr = open(PATH,O_RDONLY);if(fr==-1){perror("open fail");exit(EXIT_FAILURE);}char buffer[128];ssize_t rbytes = read(fr,buffer,sizeof(buffer));if(rbytes==-1){perror("read fail");close(fr);exit(EXIT_FAILURE);}printf("rbytes=%ld buffer=%s\n",rbytes,buffer);close(fr);return 0;
}

进程B:

#include <stdio.h>
#include <sys/types.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>#define PATH_NAME  "/home/linux/npipe"
int main()
{int result = access(PATH_NAME,F_OK);if(result == -1){int ret = mkfifo(PATH_NAME,0666);if(ret==-1){perror("mkfifo:");exit(EXIT_FAILURE);}}int fw = open(PATH_NAME,O_WRONLY);if(fw==-1){perror("open:");exit(EXIT_FAILURE);}char buf[128]={0};printf("please to enter\n");fgets(buf,sizeof(buf),stdin);buf[strlen(buf)-1]='\0';ssize_t wbytes = write(fw,buf,sizeof(buf));if(wbytes==-1){perror("write:");close(fw);exit(EXIT_FAILURE);}printf("wbytes=%ld buf=%s\n",wbytes,buf);close(fw);return 0;
}

代码解读:

进程B:

用于从有名管道(FIFO)中写入数据

定义有名管道的路径宏PATH_NAME

使用access函数检查有名管道是否存在。F_OKaccess函数的参数,用于检查文件是否存在。

如果有名管道不存在,使用mkfifo函数创建它。如果创建失败,使用perror打印错误信息,然后退出程序。

以只写模式(O_WRONLY)打开有名管道。如果打开失败,使用perror打印错误信息,然后退出程序。

定义一个字符数组buf,用于存储用户输入的数据。

使用fgets函数从标准输入读取一行数据到buffgets会读取直到换行符或缓冲区满,但不包括换行符。

buf数组中的最后一个字符(换行符)替换为字符串结束符\0

 使用write函数将用户输入的数据写入有名管道。如果写入失败,使用perror打印错误信息,关闭文件描述符fw,然后退出程序。

关闭文件描述符fw

进程A:

用于从有名管道(FIFO)中读取数据

使用open函数以只读模式(O_RDONLY)打开有名管道。如果打开失败,open函数返回-1。

如果open函数失败,使用perror打印错误信息,然后退出程序。

定义一个字符数组buffer,用于存储从有名管道读取的数据。

使用read函数从有名管道中读取数据到buffer。如果读取失败,read函数返回-1。

如果read函数失败,使用perror打印错误信息,关闭文件描述符fr,然后退出程序。

关闭文件描述符fr

结语:

无论你是初学者还是有经验的开发者,我希望我的博客能对你的学习之路有所帮助。如果你觉得这篇文章有用,不妨点击收藏,或者留下你的评论分享你的见解和经验,也欢迎你对我博客的内容提出建议和问题。每一次的点赞、评论、分享和关注都是对我的最大支持,也是对我持续分享和创作的动力

相关文章:

Linux下进程间的通信--管道

关于进程间的通信 Linux进程间通信&#xff08;Inter-Process Communication&#xff0c;IPC&#xff09;是指在多个进程之间传输数据或信号的一些方法。由于Linux中的进程有各自独立的地址空间&#xff0c;因此它们不能直接访问对方的内存。为了实现进程间的通信&#xff0c;…...

【算法】汉诺塔、顺序查找和二分查找法、冒泡排序、插入排序、选择排序

1 时间装饰器 2 汉诺塔 3 顺序查找和二分查找法 4 冒泡排序 5 插入排序 6 选择排序 1 时间装饰器 import timedef cal_time(func):def wrapper(*args, **kwargs):t1 time.time()result func(*args, **kwargs)t2 time.time()print("%s running time: %s secs." % …...

Mac电脑遇到DNS解析失败,ip可以访问,域名无法访问

当Mac电脑遇到DNS解析失败的问题时&#xff0c;可以尝试以下几个解决方法‌&#xff1a; 1.检查网络连接‌&#xff1a;确保Mac已连接到可用的网络&#xff0c;并且网络连接正常。可以尝试重新连接Wi-Fi或使用有线连接来排除网络问题。 2.清除DNS缓存‌&#xff1a;打开终端应…...

走进 “星星的孩子” 的世界:理解与关爱儿童自闭症

在这个充满生机与活力的世界里&#xff0c;有一群特殊的孩子&#xff0c;他们仿佛来自遥远的星球&#xff0c;沉浸在自己的独特世界中&#xff0c;难以与外界进行有效的沟通和互动。他们是自闭症儿童&#xff0c;也被称为 “星星的孩子”。 自闭症&#xff0c;又称孤独症谱系障…...

【学习笔记】7、存储器、复杂可编程器件和现场可编程门阵列

可编程逻辑器件PLD复杂可编程逻辑器件CPLD现场可编程门阵列FPGA 7.1 只读存储器&#xff08;ROM&#xff09; 7.1.1 ROM的结构 ROM存储器 存储阵列 地址译码器 输出控制电路 存储阵列&#xff0c;由许多存储单元&#xff08;1bit&#xff09;组成。每次读出一组数据&…...

Java面试题———RabbitMQ篇

目录 1.你们项目中哪里用到了RabbitMQ 2、为什么会选择使用RabbitMQ 3、使用RabbitMQ如何保证消息不丢失 4、消息的重复消费问题如何解决的 5、如何解决消息堆积在MQ的问题 6、RabbitMQ如何保证消费的顺序性 7、RabbitMQ的延迟队列有了解过嘛 8、RabbitMQ如何设置消息过…...

2 种方式申请免费 SSL 证书,阿里云 Certbot

如何使用免费的 SSL 证书&#xff0c;有时在项目中需要使用免费的 SSL 证书&#xff0c;Aliyun 提供免费证书&#xff0c;三个月有效期&#xff0c;可以直接在aliyun 申请&#xff0c;搜索 SSL 证书&#xff0c;选择测试证书。 Aliyun 证书需要每三月来来换一次&#xff0c;页…...

49.给出一个字符串数组,实现一个算法给定一组字符串,将字母异位词组合在一起

49. Group Anagrams 题目 给定一组字符串&#xff0c;将字母异位词组合在一起。 示例: 输入: [“eat”, “tea”, “tan”, “ate”, “nat”, “bat”] 输出: [ [“ate”,“eat”,“tea”], [“nat”,“tan”], [“bat”] ] 注意: 所有输入均为小写字母。输出的顺序可以…...

如何制作统信UOS启动盘?

如何制作统信UOS启动盘&#xff1f; 一、下载UOS系统安装镜像二、在UOS系统环境下制作启动盘步骤一&#xff1a;准备U盘步骤二&#xff1a;打开启动盘制作工具步骤三&#xff1a;选择ISO镜像文件步骤四&#xff1a;选择安装介质并格式化步骤五&#xff1a;等待制作完成 三、在W…...

Conda命令

查看当前有哪些虚拟环境 conda env list创建&#xff08;删除&#xff09;一个新的虚拟环境 conda create --name test1 python3.8 conda env remove --name test1进入和退出一个环境 conda activate test1 conda deactivate列出当前包安装的包 conda list安装包 conda in…...

perl——获取数组中元素的索引

参考&#xff1a; 如何获取数组中元素的索引 如果保证所有元素都是唯一的&#xff0c;或者只有第一个索引是感兴趣的&#xff1a; my ($index) grep { $array[$_] ~~ $element } 0 .. $#array;...

Vector vs 数组:Java中Vector相比数组的优点

每日自动更新各类学习教程及工具下载合集 ​​https://pan.quark.cn/s/874c74e8040e​​ 在Java编程中&#xff0c;数组&#xff08;Array&#xff09;和Vector都是用于存储数据的容器&#xff0c;但它们在设计和功能上有所不同。选择使用哪种数据结构取决于具体的需求。在这…...

掌握步进电机控制算法:提升自动化精度的关键(代码示例)

引言 步进电机因其高精度定位、良好的控制性能和简单的驱动方式&#xff0c;广泛应用于各类自动化设备中&#xff0c;如3D打印机、数控机床和机器人等。为了实现对步进电机的精确控制&#xff0c;采用合适的控制算法至关重要。本文将详细介绍几种常见的步进电机控制算法&#…...

MySQL的源码安装及基本部署(基于RHEL7.9)

这里源码安装mysql的5.7.44版本 一、源码安装 1.下载并解压mysql , 进入目录: wget https://downloads.mysql.com/archives/get/p/23/file/mysql-boost-5.7.44.tar.gz tar xf mysql-boost-5.7.44.tar.gz cd mysql-5.7.44/ 2.准备好mysql编译安装依赖: yum install cmake g…...

RUP-系统架构师(五十六)

1在RUP中采用“41”视图模型来描述软件系统的体系结构。在该模型中&#xff0c;最终用户侧重于&#xff08;&#xff09;&#xff0c;系统工程师侧重于&#xff08;&#xff09;。 问题1 问题2 A 实现视图 B 进程视图 C 逻辑视图 D 部署视图 解析&#xff1a; RUP有 逻辑…...

【大模型系列篇】人工智能与智能计算的发展

&#x1f525;&#x1f525;&#x1f525; 来自 中国工程院院士、中国科学院计算技术研究所研究员 孙凝晖 第十四届全国人大常委会专题讲座上的讲稿《人工智能与智能计算的发展》 “把新一代人工智能作为推动科技跨越发展、 产业优化升级、生产力整体跃升的驱动力量&#xff0c…...

C++ | Leetcode C++题解之第365题水壶问题

题目&#xff1a; 题解&#xff1a; class Solution { public:bool canMeasureWater(int x, int y, int z) {if (x y < z) {return false;}if (x 0 || y 0) {return z 0 || x y z;}return z % gcd(x, y) 0;} };...

c++-类(中)

c-类&#xff08;中&#xff09; 一、类的默认成员函数1.1 什么是默认成员函数&#xff1f;1.2 默认成员函数有哪些&#xff1f; 二、构造函数2.1 什么是构造函数&#xff1f;2.2 构造函数的特点 三、析构函数3.1 什么是析构函数&#xff1f;3.2 析构函数的特点 四、拷贝构造函…...

在 Python 中查找列表中的重复元素

在 Python 中查找列表中的重复元素 在数据处理和分析中,查找重复元素是一个常见的任务。无论是在数据清洗、用户输入验证还是统计分析中,识别和处理重复数据都是至关重要的。在 Python 中,有多种方法可以查找列表中的重复元素。本文将详细介绍这些方法,包括示例代码、性能…...

Kafka【一】Windows下安装单节点Kafka

① 下载 下载软件安装包&#xff1a;kafka_2.12-3.6.1.tgz&#xff0c;下载地址&#xff1a;https://kafka.apache.org/downloads 这里的3.6.1&#xff0c;是Kafka软件的版本。截至到2023年12月24日&#xff0c;Kafka最新版本为3.6.1。2.12是对应的Scala开发语言版本。Scala2…...

国防科技大学计算机基础课程笔记02信息编码

1.机内码和国标码 国标码就是我们非常熟悉的这个GB2312,但是因为都是16进制&#xff0c;因此这个了16进制的数据既可以翻译成为这个机器码&#xff0c;也可以翻译成为这个国标码&#xff0c;所以这个时候很容易会出现这个歧义的情况&#xff1b; 因此&#xff0c;我们的这个国…...

在软件开发中正确使用MySQL日期时间类型的深度解析

在日常软件开发场景中&#xff0c;时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志&#xff0c;到供应链系统的物流节点时间戳&#xff0c;时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库&#xff0c;其日期时间类型的…...

FFmpeg 低延迟同屏方案

引言 在实时互动需求激增的当下&#xff0c;无论是在线教育中的师生同屏演示、远程办公的屏幕共享协作&#xff0c;还是游戏直播的画面实时传输&#xff0c;低延迟同屏已成为保障用户体验的核心指标。FFmpeg 作为一款功能强大的多媒体框架&#xff0c;凭借其灵活的编解码、数据…...

React19源码系列之 事件插件系统

事件类别 事件类型 定义 文档 Event Event 接口表示在 EventTarget 上出现的事件。 Event - Web API | MDN UIEvent UIEvent 接口表示简单的用户界面事件。 UIEvent - Web API | MDN KeyboardEvent KeyboardEvent 对象描述了用户与键盘的交互。 KeyboardEvent - Web…...

AI书签管理工具开发全记录(十九):嵌入资源处理

1.前言 &#x1f4dd; 在上一篇文章中&#xff0c;我们完成了书签的导入导出功能。本篇文章我们研究如何处理嵌入资源&#xff0c;方便后续将资源打包到一个可执行文件中。 2.embed介绍 &#x1f3af; Go 1.16 引入了革命性的 embed 包&#xff0c;彻底改变了静态资源管理的…...

Mysql中select查询语句的执行过程

目录 1、介绍 1.1、组件介绍 1.2、Sql执行顺序 2、执行流程 2.1. 连接与认证 2.2. 查询缓存 2.3. 语法解析&#xff08;Parser&#xff09; 2.4、执行sql 1. 预处理&#xff08;Preprocessor&#xff09; 2. 查询优化器&#xff08;Optimizer&#xff09; 3. 执行器…...

QT3D学习笔记——圆台、圆锥

类名作用Qt3DWindow3D渲染窗口容器QEntity场景中的实体&#xff08;对象或容器&#xff09;QCamera控制观察视角QPointLight点光源QConeMesh圆锥几何网格QTransform控制实体的位置/旋转/缩放QPhongMaterialPhong光照材质&#xff08;定义颜色、反光等&#xff09;QFirstPersonC…...

Java编程之桥接模式

定义 桥接模式&#xff08;Bridge Pattern&#xff09;属于结构型设计模式&#xff0c;它的核心意图是将抽象部分与实现部分分离&#xff0c;使它们可以独立地变化。这种模式通过组合关系来替代继承关系&#xff0c;从而降低了抽象和实现这两个可变维度之间的耦合度。 用例子…...

深度学习水论文:mamba+图像增强

&#x1f9c0;当前视觉领域对高效长序列建模需求激增&#xff0c;对Mamba图像增强这方向的研究自然也逐渐火热。原因在于其高效长程建模&#xff0c;以及动态计算优势&#xff0c;在图像质量提升和细节恢复方面有难以替代的作用。 &#x1f9c0;因此短时间内&#xff0c;就有不…...

解读《网络安全法》最新修订,把握网络安全新趋势

《网络安全法》自2017年施行以来&#xff0c;在维护网络空间安全方面发挥了重要作用。但随着网络环境的日益复杂&#xff0c;网络攻击、数据泄露等事件频发&#xff0c;现行法律已难以完全适应新的风险挑战。 2025年3月28日&#xff0c;国家网信办会同相关部门起草了《网络安全…...