【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♪(・ω・)ノ

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

智能家居完结 -- 整体设计

系统框图 前情提要: 智能家居1 -- 实现语音模块-CSDN博客 智能家居2 -- 实现网络控制模块-CSDN博客 智能家居3 - 实现烟雾报警模块-CSDN博客 智能家居4 -- 添加接收消息的初步处理-CSDN博客 智能家居5 - 实现处理线程-CSDN博客 智能家居6 -- 配置 ini文件优化设备添加-CS…

fastadmin 树状菜单展开,合并;简要文件管理系统界面设计与实现

一&#xff0c;菜单合并效果图 源文件参考&#xff1a;fastadmin 子级菜单展开合并、分类父级归纳 - FastAdmin问答社区 php服务端&#xff1a; public function _initialize() {parent::_initialize();$this->model new \app\admin\model\auth\Filetype;$this->admin…

粤嵌—2024/5/21—打家劫舍(✔)

代码实现&#xff1a; int rob(int *nums, int numsSize) {if (numsSize 1) {return nums[0];}if (numsSize 2) {return fmax(nums[0], nums[1]);}int dp[numsSize];dp[0] nums[0];dp[1] fmax(nums[0], nums[1]);for (int i 2; i < numsSize; i) {dp[i] fmax(dp[i - 1…

东方通TongWeb结合Spring-Boot使用

一、概述 信创需要; 原状:原来的服务使用springboot框架,自带的web容器是tomcat,打成jar包启动; 需求:使用东方通tongweb来替换tomcat容器; 二、替换步骤 2.1 准备 获取到TongWeb7.0.E.6_P7嵌入版 这个文件,文件内容有相关对应的依赖包,可以根据需要来安装到本地…

vue/core源码中ref源码的js化

起源&#xff1a; 当看见reactivity文件中的ref.ts文件长达五百多的ts代码后&#xff0c;突发奇想想看下转化成js有多少行。 进行转化&#xff1a; let shouldTrack true; // Define shouldTrack variable let activeEffect null; // Define activeEffect variable// 定义…

Android9.0 MTK平台如何增加一个系统应用

在安卓定制化开发过程中&#xff0c;难免遇到要把自己的app预置到系统中&#xff0c;作为系统应用使用&#xff0c;其实方法有很多&#xff0c;过程很简单&#xff0c;今天分享一下我是怎么做的&#xff0c;共总分两步&#xff1a; 第一步&#xff1a;要找到当前系统应用apk存…

【数据结构与算法 经典例题】判断链表是否带环

&#x1f493; 博客主页&#xff1a;倔强的石头的CSDN主页 &#x1f4dd;Gitee主页&#xff1a;倔强的石头的gitee主页 ⏩ 文章专栏&#xff1a;数据结构与算法刷题系列&#xff08;C语言&#xff09; 期待您的关注 目录

互联网十万个为什么之 什么是Kubernetes(K8s)?

Kubernetes&#xff08;通常简称为K8s&#xff09;是一款用于自动部署、扩缩和管理容器化应用程序的开源容器编排平台。Kubernetes已发展为现代企业实现敏捷开发、快速迭代、资源优化及灵活扩展的关键技术组件之一。它拥有庞大的开源社区和丰富的生态系统。围绕Kubernetes已经形…

深度强化学习 Actor-Critic演员评论家 PPO

将策略(Policy Based)和价值(Value Based)相结合的方法&#xff1a;Actor-Critic算法&#xff0c;在强化学习领域最受欢迎的A3C算法&#xff0c;DDPG算法&#xff0c;PPO算法等都是AC框架。 一、Actor-Critic算法简介 Actor-Critic从名字上看包括两部分&#xff0c;演员(Actor…

《拯救大学生课设不挂科第四期之蓝桥杯是什么?我是否要参加蓝桥杯?选择何种语言?如何科学备赛?方法思维教程》【官方笔记】

背景&#xff1a; 有些同学在大一或者大二可能会被老师建议参加蓝桥杯&#xff0c;本视频和文章主要是以一个过来人的身份来给与大家一些思路。 比如蓝桥杯是什么&#xff1f;我是否要参加蓝桥杯&#xff1f;参加蓝桥杯该选择何种语言&#xff1f;如何科学备赛&#xff1f;等…

《最新出炉》系列入门篇-Python+Playwright自动化测试-41-录制视频

宏哥微信粉丝群&#xff1a;https://bbs.csdn.net/topics/618423372 有兴趣的可以扫码加入 1.简介 上一篇讲解和分享了录制自动生成脚本&#xff0c;索性连带录制视频也一股脑的在这里就讲解和分享了。今天我们将学习如何使用Playwright和Python来录制浏览器操作的视频&#…

19 QinQ技术(Vlan两层封装)

1 什么是QinQ&#xff1f; QinQ&#xff08;802.1Q-in-802.1Q&#xff09;&#xff0c;也叫做VLAN Stacking或Double VLAN&#xff0c;由IEEE 802.1ad标准定义&#xff0c;**是一项扩展VLAN空间的技术&#xff0c;**通过在802.1Q标签报文的基础上再增加一层802.1Q的Tag来达到扩…

1738. 找出第 K 大的异或坐标值

题目&#xff1a; 给你一个二维矩阵 matrix 和一个整数 k &#xff0c;矩阵大小为 m x n 由非负整数组成。 矩阵中坐标 (a, b) 的 值 可由对所有满足 0 < i < a < m 且 0 < j < b < n 的元素 matrix[i][j]&#xff08;下标从 0 开始计数&#xff09;执行异…

架构师必考题--软件系统质量属性

软件系统质量属性 1.质量属性2.质量属性场景描述3.系统架构评估 这个知识点是系统架构师必考的题目&#xff0c;也是案例分析题第一题&#xff0c; 有时候会出现在选择题里面&#xff0c;考的分数也是非常高的。 1.质量属性 属性说明可用性错误检测/恢复/避免性能资源需求/管理…

链游:区块链技术的游戏新纪元

随着区块链技术的快速发展&#xff0c;越来越多的行业开始探索与其结合的可能性&#xff0c;其中&#xff0c;游戏行业与区块链的结合尤为引人注目。链游&#xff0c;即基于区块链技术的游戏&#xff0c;正以其独特的优势&#xff0c;为玩家带来全新的游戏体验。本文将对链游进…

AI数据面临枯竭

Alexandr Wang&#xff1a;前沿研究领域需要大量当前不存在的数据&#xff0c;未来会受到这个限制 Alexandr Wang 强调了 AI 领域面临的数据问题。 他指出&#xff0c;前沿研究领域&#xff08;如多模态、多语言、专家链式思维和企业工作流&#xff09;需要大量当前不存在的数…

java欢迪迈手机商城设计与实现源码(springboot+vue+mysql)

风定落花生&#xff0c;歌声逐流水&#xff0c;大家好我是风歌&#xff0c;混迹在java圈的辛苦码农。今天要和大家聊的是一款基于springboot的欢迪迈手机商城设计与实现。项目源码以及部署相关请联系风歌&#xff0c;文末附上联系信息 。 项目简介&#xff1a; 欢迪迈手机商城…

【Python从入门到进阶】55、使用Python轻松操作Mysql数据库

一、引言 1、MySQL数据库简介 MySQL是一个开源的关系型数据库管理系统&#xff08;RDBMS&#xff09;&#xff0c;它使用了一种名为Structured Query Language&#xff08;SQL&#xff09;的查询语言来管理数据。MySQL因其高性能、可扩展性、易用性和稳定性而广受欢迎&#x…

<商务世界>《75 微课堂<茶叶(1)-质量分级>》

1 中国茶叶分级 中国的10级标准是按照茶叶的外观、香气、滋味、汤色、叶底五个方面进行评分&#xff0c;分别用10分制进行评分&#xff0c;总分为50分&#xff0c;得分越高&#xff0c;茶叶的品质就越高。具体的分数和等级如下表所示&#xff1a; 2 每级的特点 茶叶的质量等级…

zabbix“专家坐诊”第240期问答

问题一 Q&#xff1a;zabbix6.0版本&#xff0c;配置报警媒介里的message 消息时&#xff0c;操作数据参数EVENT.OPDATA调用的参数是哪个&#xff1f; A&#xff1a;参考 问题二 Q&#xff1a;请问告警为什么只有关闭之前的告警&#xff0c;才会生成新的告警&#xff1f; A&a…