【Linux杂货铺】进程通信

目录
🌈 前言🌈
📁 通信概念
📁 通信发展阶段
📁 通信方式
📁 管道(匿名管道)
📂 接口
编辑📂 使用fork来共享通道
📂 管道读写规则
📂 管道特征
📁 命名管道
📂 接口
📂 管道和命名管道的区别
📁 System V IPC
📁 共享内存
📂 原理
📂 接口
📁 消息队列
📁 信号量
📂 进程互斥
📁 总结
🌈 前言🌈
欢迎收看本期【Linux杂货铺】,本期内容将讲解进程是如何实现通信的,即资源共享。本篇文章主要聚焦于本地通信。重点讲解管道,共享内存实现进程通信,拓展了解消息队列,信号量等内容。
📁 通信概念
进程通信是什么,这里就不做阐述了,就如字面意思,让进程之间信息交流。
通信的目的有:
1. 数据传输:一个进程需要将它的数据发送给另一个进程。
2. 资源共享:多个进程之间共享同样的资源。
3. 通知事件:一个进程需要向另一个或一组进程发送消息,通知它们发生了某种事件(如子进程终止通知父进程)
4. 进程控制:有些进程希望完全控制另一个进程的执行(Debug进程),此时控制进程希望能拦截另一个进程的所有陷入和异常,并能及时知道它的状态。
📁 通信发展阶段
在Linux中,进程通信的发展阶段经历了几个阶段,主要包含以下几个阶段:
1. 初始阶段:最早期的Linux内核中,进程通信方式相对有限,主要依赖于管道(Pipe) 和 信号(Signal)这样的基础机制。此时通信较为简单和有限。
2. System V IPC : 随着Linux的发展,引入了System V IPC,它是一组用于进程间通信的API(Application Programming Interface),.System V IPC包括了共享内存(Shared Memory)、信号量(Semaphore)和消息队列(Message Queue)等机制。
3. POSIX IPC:随着Linux逐渐趋近POSIX(Portable Operating System Interface)标准,进程通信也逐渐向POSIX IPC过渡。POSIX IPC是一套与平台无关的进程通信接口,包括命名管道(Named Pipe)、共享内存(Shared Memory)、信号量(Semaphore)和消息队列(Message Queue)等。
4. Socket编程:随着互联网的兴起和网络技术的发展,Socket编程成为Linux中重要的进程通信方式。通过Socket编程,进程可以在不同主机之间进行通信,实现远程进程间的通信和数据交换。
5. 其他高级通信机制:随着分布式系统和多线程编程的发展,还出现了更多高级的进程通信机制,如RPC(Remote Procedure Call,远程过程调用)、MPI(Message Passing Interface,消息传递接口)等。
📁 通信方式
在Linux中,我们可以将进程通信分为一下多种方式:
1. 管道(Pipe): 是一种半双工(一段度,另一端只能写)的通信方式,适用于具有父子关系的进程通信。可以实现一个进程将输出数据传递到另一个进程进行输入。
2. 命名管道(Name Pipe):是一种特殊的文件,可用于不想管的进程之间通信。与普通管道不同,命名管道通过文件系统进行访问。
3. 信号(Signal):是一种轻量级的进程通信机制,用于在进程之间发送异步通知。一个进程向另一个进程发送信号,接受方式根据不同信号类型采取相应的处理操作。
4. 共享内存(Shared Memory):共享内存是一种高效的进程间通信方式,允许多个进程共享同一块物理内存区域。进程可以直接读写共享内存,避免了数据的复制和传输开销。
5. 信号量(Semaphore):信号量是一种计数器,用于控制多个进程对共享资源的访问。通过对信号量进行加减操作,进程可以申请和释放共享资源,实现进程间的互斥和同步。
6. 消息队列(Message Queue):消息队列是一种按照消息的方式进行进程间通信的机制。进程可以往消息队列中发送消息,并从消息队列中接收消息,实现异步通信和解耦合。
7. 套接字(Socket):套接字是一种网络编程接口,也可以用于进程间通信。通过创建套接字,进程可以在不同主机之间进行通信,实现远程进程的通信和数据交换。
以上这些进程通信方式在Linux中都有对应的系统调用和库函数来支持,开发者可以根据具体需求选择合适的方式进行进程间通信。
📁 管道(匿名管道)
管道式Unix中最古老的进程间通信的形式。我们吧从一个进程链接到另一个进程的一个数据流称为一个“管道”

📂 接口
#include <unistd.h>
功能:创建一无名管道
原型
int pipe(int fd[2]);
参数
fd:文件描述符数组,其中fd[0]表示读端, fd[1]表示写端
返回值:成功返回0,失败返回错误代码
📂 使用fork来共享通道

通过文件描述符表来理解,父子进程如何确定同一个通道。

在内核里,管道的本质就是一块内核级的文件空间。

📂 管道读写规则
1. 如果管道内部是空的 , 并且wfd没有关闭,读取条件不具备,所以读进程被阻塞,等待读取条件成立,即对端写入数据。
2. 向管道写,并且rfd不读且没有关闭,管道写满了,写进程会被阻塞,等待写条件具备,即对端读取数据。
3. 管道一直在读,但wfd写端关闭,读端的read会读到0,表示读到文件结尾。
4. 读端rfd关闭,写端wfd不会一直写入,一旦写入进程会杀掉。会给进程发送信号 (13号信号)。
📂 管道特征
.1. 匿名管道只能用来进行具有血缘关系的进程之间,进行通信,常用于父子进程之间通信。
2. 管道内部,自带进程之间同步的机制。
3. 管道文件的生命周期是随进程的。
4. 管道文件在通信的时候,是面向字节流的,write的次数和读取的次数不是一一匹配的。
5.管道的通信方式,是一种特殊的半双工模式。
管道的特征对命名管道同样适应。
📁 命名管道
管道应用的一个限制就是只能具有共同的祖先(具有血缘关系)的进程间通信。
如果我们想要不想管的进程之间通信,可以使用命名管道(FIFO)。命名管道是一种特殊的文件。
管道(匿名,命名)是内核级的,不与磁盘进行交互,即不会讲数据刷新到磁盘。
📂 接口
命名管道,之所以叫命名管道是因为需要有名字,不同进程之间如何知道一个命名管道呢,就是通过具有唯一性的文件路径,通过文件路径找到这个命名管道,并进行文件读写操作。
因此,我们在创建命名管道的时候,需要提供文件路径,以此来创建命名管道文件。
指令
mkfifo filename系统调用
int mkfifo(const char *filename,mode_t mode);mode是指权限。
//创建管道文件#include <iostream>
#include <sys/types.h>
#include <sys/stat.h>int main()
{mkfifo("./fifo",0x666);return 0;
}

删除管道指令
unlink filename删除管道接口
#include <unistd.h>int unlink(const char* pathname)
#include <iostream>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>int main()
{mkfifo("./fifo",0x666);sleep(5); //过5秒后,清除命名管道文件unlink("./fifo");return 0;
}

📂 管道和命名管道的区别
1. 管道通过pipe函数创建并打开。
2. 命名管道有mkfifo函数创建,打开用open。
3. FIFO(命名管道)和 pipe(匿名管道)之间唯一的区别分别在它们的创建与打开的方式不同,一旦这些工作完成之后,它们具有相同的意义。
📁 System V IPC
System V IPC(Inter-Process Communication)是一种在Unix-like操作系统中用于进程间通信的机制。它提供了三种主要的IPC对象:消息队列(Message Queues)、信号量(Semaphores)和共享内存(Shared Memory),这些对象允许不同的进程在同一台计算机上进行通信和共享数据。
经过不断发展,进程通信有了更好的方式,即通过网络进行通信,所以单纯的本地通信已经很少用到,因此我们将主要讲解共享内存,因为相比较足够简单,如果感兴趣可以学习了解消息队列和信号量。
📁 共享内存
共享内存区是最快的IPC形式。一旦这样的内存映射到共享它的进程的地址空间,这些进程间数据传递不再涉及到内核,换句话说是进程不再通过执行进入内核的系统调用来传递彼此的数据。
📂 原理

在物理内存中创建一段空间,建立与虚拟地址空间的映射映射到虚拟地址空间中的共享区。此后两进程的通信再也不需要再进入内核态调用系统调用,直接通过代码读写共享区即可,例如malloc出一段空间,通过指针来使用这段空间。
对于上面操作,需要理解:
1. 以上操作都是OS操作的,如共享内存的映射。
2. OS必须提供系统调用,供进程使用。如开辟共享内存。
3. 共享内存可以在系统中存在多份,供不同个数,不同进程进行通信。
4. OS要对共享内存进行管理,即共享内存不是简单的一段内存空间,也要有描述和管理共享内存的数据结构和匹配算法。
5. 共享内存 = 内存空间(数据) + 属性。
📂 接口
1. 创建一个共享内存
#include <sys/ipc.h>
#include <sys/shm.h>
int shmget(key_t key, size_t size, int shmflg);
a. size:是用来指示共享内存空间的大小。
b. shmflag:用于指定共享内存区域的权限和选项。IPC_CREAT 和 IPC_EXCL
IPC_CREAT:如果要创建的共享内存在OS内不存在,就创建,如果存在,就获取并返回。
IPC_EXCL:不能单独使用,必须和IPC_CREAT组合。
IPC_CREAT | IPC_EXCL:如果不存在,创建;存在,出错并返回。
c. key:唯一标识共享内存区域的键值。这是用户提供给系统使用的具有唯一性的键值。
这里为什么要用户自己提供呢?不可以OS自己生成一个吗?不可以,我们的出发点就是通过共享内存实现两个进程通信,如果两个进行都知道这个key,那还大费周章干什么,直接通信就好了。
d. 返回值 shmid:也是一个唯一标识共享区域的键值。不过它是系统提供给用户使用的。这主要是为了解耦。
shmid 与 key 的区别:
1. key是用户设置,内核使用的字段,用户不能使用key来进行shm管理。key是内核区分shm唯一性的。
2. shmid是内核返回给用户的一个标识符,用来进行用户级,对共享内存进行操作的。
2. 挂载共享内存
共享内存想要使用,必须先将物理内存与虚拟内存进行映射。因此需要将共享内存挂接。
#include <sys/types.h>
#include <sys/shm.h>//挂接 , 只需要输入shmid 即可 ,其他分别输入 nullptr , 0
//失败返回0,成功返回共享内存的起始地址。
void *shmat(int shmid, const void *shmaddr, int shmflg);//取消挂接,只需要输入挂接成功后返回的地址。
int shmdt(const void *shmaddr);
3. 删除共享内存
#include <sys/ipc.h>
#include <sys/shm.h>int shmctl(int shmid, int cmd, struct shmid_ds *buf);
//第二个参数为 IPC_RMID , 第三个参数为 nullptr
4. 指令查看 和 删除
ipcs -m : 查看ipcrm -m shmid : 删除
此外,我们还需要认识到,共享内存/消息队列/信号量 的生命周期随内核的,即进程的结束并不会受到影响,必须手动释放(指令 或 系统调用),否则会一直存在。
管道的生命周期随内核。
📁 消息队列
消息队列提供了一个从一个进程向另外一个进程发送一块数据的方法
每个数据块都被认为是有一个类型,接收者进程接收的数据块可以有不同的类型值
特性方面 :IPC资源必须删除,否则不会自动清除,除非重启,所以system V IPC资源的生命周期随内核
📁 信号量
严格来说,信号量是一种用于实现进程间同步和互斥的机制,通过它可以控制对共享资源的访问。
信号量是一种计数器,用于控制多个进程对共享资源的访问。通过对信号量进行加减操作,进程可以申请和释放共享资源,实现进程间的互斥和同步。
需要经过申请信号量,访问共享内存,释放信号量 这几个过程。
因为信号量本身是一种共享资源,需要被所有进程看到,因此也列为进程通信的范畴。
📂 进程互斥
我们需要重申几个概念:
1. 多个执行流能看到的一份资源:共享资源。
2. 被保护起来的资源,叫做 临界资源。保护资源的方式:同步 and 互斥。
3. 互斥 : 任何时刻只能有一个进程在访问共享资源。
4. 代码 = 访问共享资源的代码(临界区) + 不访问公共享资源的代码(非临界区)
5. 对共享资源进行保护,本质是对共享资源的代码进行保护。
由于各进程要求共享资源,而且有些资源需要互斥使用,因此各进程间竞争使用这些资源,进程的这种 关系为进程的互斥。
系统中某些资源一次只允许一个进程使用,称这样的资源为临界资源或互斥资源。
在进程中涉及到互斥资源的程序段叫临界区。
在多线程的章节里,我们会讲解信号量,这里先做一定的了解。
📁 总结
因此,进程本地通信的方式截止目前,我们学习了管道,命名管道,共享内存,了解了消息队列和信号量。介绍了进程通信的发展历史阶段,上述三种通信方式的系统调用接口和指令。拓展了进程互斥的概念,为日后学习多线程做了铺垫。
以上,就是本期【Linux杂货铺】的主要内容了,如果感觉本篇文章对你有帮助,欢迎点赞收藏,关注Thanks♪(・ω・)ノ

相关文章:
【Linux杂货铺】进程通信
目录 🌈 前言🌈 📁 通信概念 📁 通信发展阶段 📁 通信方式 📁 管道(匿名管道) 📂 接口 编辑📂 使用fork来共享通道 📂 管道读写规则 &…...
常用API(正则表达式、爬取、捕获分组和非捕获分组 )
1、正则表达式 练习——先爽一下正则表达式 正则表达式可以校验字符串是否满足一定的规则,并用来校验数据格式的合法性。 需求:假如现在要求校验一个qq号码是否正确。 规则:6位及20位之内,0不能在开头,必须全部是数字…...
JVM学习-Class文件结构②
访问标识(access_flag) 在常量池后,紧跟着访问标记,标记使用两个字节表示,用于识别一些类或接口层次的访问信息,包括这个Class是类还是接口,是否定义为public类型,是否定义为abstract类型,如果…...
数据库连接项目
MySQL...
MySQL--InnoDB体系结构
目录 一、物理存储结构 二、表空间 1.数据表空间介绍 2.数据表空间迁移 3.共享表空间 4.临时表空间 5.undo表空间 三、InnoDB内存结构 1.innodb_buffer_pool 2.innodb_log_buffer 四、InnoDB 8.0结构图例 五、InnoDB重要参数 1.redo log刷新磁盘策略 2.刷盘方式&…...
ffplay 使用文档介绍
ffplay ffplay 是一个简单的媒体播放器,它是 FFmpeg 项目的一部分。FFmpeg 是一个广泛使用的多媒体框架,能够解码、编码、转码、复用、解复用、流化、过滤和播放几乎所有类型的媒体文件。 ffplay 主要用于测试和调试,因为它提供了一个命令行界面,可以方便地查看媒体文件的…...
四种网络IO模型
📝个人主页:五敷有你 🔥系列专栏:面经 ⛺️稳中求进,晒太阳 IO的定义 IO是计算机内存与外部设备之间拷贝数据的过程。CPU访问内存的速度远高于外部设备。因此CPU是先把外部设备的数据读取到内存,在…...
Mixed-precision计算原理(FP32+FP16)
原文: https://lightning.ai/pages/community/tutorial/accelerating-large-language-models-with-mixed-precision-techniques/ This approach allows for efficient training while maintaining the accuracy and stability of the neural network. In more det…...
Go 控制协程(goroutine)的并发数量
在使用协程并发处理某些任务时, 其并发数量往往因为各种因素的限制不能无限的增大. 例如网络请求、数据库查询等等。 从运行效率角度考虑,在相关服务可以负载的前提下(限制最大并发数),尽可能高的并发。 在Go语言中,…...
web安全渗透测试十大常规项(一):web渗透测试之CSRF跨站请求伪造
渗透测试之CSRF跨站请求伪造 CSRF跨站请求伪造 CSRF跨站请求伪造...
YOLOv10尝鲜测试五分钟极简配置
最近清华大学团队又推出YOLOv10,真是好家伙了。 安装: pip install supervision githttps://github.com/THU-MIG/yolov10.git下载权重:https://github.com/THU-MIG/yolov10/releases/download/v1.0/yolov10n.pt 预测: from ult…...
社交媒体数据恢复:聊天宝
请注意,本教程仅针对聊天宝应用程序,而非其他聊天软件。以下是详细的步骤: 首先,请确保您已经登录了聊天宝应用程序。如果您尚未登录,请使用您的账号登录。 在聊天宝主界面,找到您希望恢复聊天记录的对话框…...
备战秋招—模拟版图面试题来了
随着暑期的脚步逐渐临近,电子工程和集成电路设计领域的毕业生们,也将迎来了另一个求职的黄金期——秋招。我们总说机会是留给有准备的人。对于有志于投身于模拟版图设计的学子们来说,为了在众多求职者中脱颖而出,充分备战模拟版图…...
CAN总线简介
1. CAN总线概述 1.1 CAN定义与历史背景 CAN,全称为Controller Area Network,是一种基于消息广播的串行通信协议。它最初由德国Bosch公司在1983年为汽车行业开发,目的是实现汽车内部电子控制单元(ECUs)之间的可靠通信。…...
【HSQL001】HiveSQL内置函数手册总结(更新中)
1.熟悉、梳理、总结下Hive SQL相关知识体系。 2.日常研发过程中使用较少,随着时间的推移,很快就忘得一干二净,所以梳理总结下,以备日常使用参考 3.欢迎批评指正,跪谢一键三连! 文章目录 1.函数清单 1.函数清…...
Rust面试宝典第14题:旋转数组
题目 给定一个数组,将数组中的元素向右移动k个位置,其中k是非负数。要求如下: (1)尽可能想出更多的解决方案,至少有三种不同的方法可以解决这个问题。 (2)使用时间复杂度为O(n)和空间…...
解决SpringBoot中插入汉字变成?(一秒解决)
在这里url后面加一行配置即可&useUnicodetrue&characterEncodingUTF-8即可 解释 spring.datasource.url: 这里包含了数据库的URL,以及额外的参数如useUnicodetrue用于启用Unicode字符集支持,characterEncodingUTF-8用于指定字符编码为UTF-8&…...
5.26牛客循环结构
1002. 难点: 两层循环条件设置 思路 可以设置三个变量 代码 1003 思路: 与星号双塔差不多,在此基础上加大一点难度 每日练题5.23 (EOF用法)-CSDN博客 代码 1004 代码...
AIGC 004-T2I-adapter另外一种支持多条件组合控制的文生图方案!
AIGC 004-T2I-adapter另外一种支持多条件组合控制的文生图方案! 文章目录 0 论文工作1 论文方法2 效果 0 论文工作 T2I-Adapter 论文提出了一种名为 T2I-Adapter 的轻量级适配器模块,旨在增强文本到图像 (T2I) 扩散模型的语义理解和生成能力。 论文指出…...
详解 Cookies 和 WebStorage
Cookies 和 WebStorage Cookies 和 WebStorageCookies简要介绍操作 Cookies(document.cookie)不足之处 WebStorage简要介绍LocalStorage Vs. SessionStorage操作 WebStorage 三种数据存储方式的对比分析共性差异 REFERENCES Cookies 和 WebStorage Cook…...
AI圈内火热的Agent、MCP、Skill、CLI是啥?用装修房子讲透,看完秒懂
本文用装修房子的比喻,详细解释了AI领域的四个核心概念:Agent如同会自主规划任务的私人助理;MCP是AI与外部工具数据的统一接口,类似USB-C;Skill是指导AI按标准操作执行的手册;CLI则是不依赖图形界面的命令行…...
flameshow性能优化技巧:如何快速定位Go程序中的CPU热点
flameshow性能优化技巧:如何快速定位Go程序中的CPU热点 【免费下载链接】flameshow A terminal Flamegraph viewer. 项目地址: https://gitcode.com/gh_mirrors/fl/flameshow 🔥 想要快速定位Go程序中的性能瓶颈吗?flameshow是一个强大…...
League Akari:如何通过LCU API实现英雄联盟游戏流程的智能化管理?
League Akari:如何通过LCU API实现英雄联盟游戏流程的智能化管理? 【免费下载链接】League-Toolkit An all-in-one toolkit for LeagueClient. Gathering power 🚀. 项目地址: https://gitcode.com/gh_mirrors/le/League-Toolkit Leag…...
别再乱建索引了!用Explain的key_len字段,一眼看穿你的MySQL联合索引到底生效了几个字段
解密MySQL联合索引:用key_len精准判断索引生效范围 在数据库性能优化领域,联合索引的使用一直是个既基础又容易踩坑的话题。很多开发者虽然知道"最左匹配原则"这个名词,但在实际业务场景中,面对复杂的查询条件组合时&a…...
从无线破解到PDF解密:盘点那些容易被忽略的‘非主流’密码审计场景与工具
密码安全审计的隐秘战场:从无线网络到加密文档的实战指南 当大多数人谈论密码安全时,脑海中浮现的往往是服务器登录、数据库访问这些企业级场景。然而在数字生活的每个角落,从家庭Wi-Fi到工作文档,密码保护的脆弱性同样可能成为安…...
CMSIS-DAP调试器原理与应用:以Elektor mbed interface为例
1. 项目概述:Elektor mbed interface [150554] 是什么?如果你玩过ARM Cortex-M系列的单片机,尤其是NXP LPC800系列,那你可能对“CMSIS-DAP”这个调试器标准不陌生。它是由ARM官方推出的一个开源调试接口标准,最大的好处…...
基于STM32WL与LoRaWAN的远程空气质量监测系统全栈开发实践
1. 项目概述:构建一个远程空气质量监测系统最近在做一个挺有意思的玩意儿:一个能自己找地方待着、靠太阳能供电,然后把周围空气数据悄无声息传回来的远程监测终端。核心想法很简单,就是想知道某个犄角旮旯,比如工厂周边…...
昇腾CANN cmake 实战:CANN CMake 构建系统——跨平台编译配置与模块化管理
8 个 CANN 仓库各需独立构建(ops-transformer/ops-nn/hccl/ge/…)→ 手写 8 套 CMakeLists.txt(CANN 路径判断、跨 NPU 型号编译、第三方库兼容)。cmake 仓库提供统一的 FindCANN.cmake CANNConfig.cmake 模板——任何仓库只需 f…...
5分钟免费搞定HS2汉化:Honey Select 2完整中文补丁终极教程
5分钟免费搞定HS2汉化:Honey Select 2完整中文补丁终极教程 【免费下载链接】HS2-HF_Patch Automatically translate, uncensor and update HoneySelect2! 项目地址: https://gitcode.com/gh_mirrors/hs/HS2-HF_Patch 还在为Honey Select 2的日文界面而烦恼吗…...
茉莉花插件:如何让中文文献管理效率提升300%
茉莉花插件:如何让中文文献管理效率提升300% 【免费下载链接】jasminum A Zotero add-on to retrive CNKI meta data. 一个简单的Zotero 插件,用于识别中文元数据 项目地址: https://gitcode.com/gh_mirrors/ja/jasminum 还在为中文文献的元数据抓…...

