【Linux进程间通信(六)】深入理解 System V IPC

         (一)引入

(二)IPC 命名空间

(三)ipc_ips结构体

(四)ipc_id_ary结构体

(五)kern_ipc_perm结构体

(六)操作系统对IPC资源是如何管理的


(一)引入

在前三篇的博客中,我介绍了System V IPC在Linux中的三种方式:共享内存、消息队列以及信号量。观察这三种IPC资源的内核数据:

共享内存:

           struct shmid_ds {
               struct ipc_perm shm_perm;    /* Ownership and permissions */
               size_t          shm_segsz;   /* Size of segment (bytes) */
               time_t          shm_atime;   /* Last attach time */
               time_t          shm_dtime;   /* Last detach time */
               time_t          shm_ctime;   /* Creation time/time of last
                                               modification via shmctl() */
               pid_t           shm_cpid;    /* PID of creator */
               pid_t           shm_lpid;    /* PID of last shmat(2)/shmdt(2) */
               shmatt_t        shm_nattch;  /* No. of current attaches */
               ...
           };

 消息队列:

           struct msqid_ds {
               struct ipc_perm msg_perm;   /* Ownership and permissions */
               time_t          msg_stime;  /* Time of last msgsnd(2) */
               time_t          msg_rtime;  /* Time of last msgrcv(2) */
               time_t          msg_ctime;  /* Time of creation or last
                                              modification by msgctl() */
               unsigned long   msg_cbytes; /* # of bytes in queue */
               msgqnum_t       msg_qnum;   /* # number of messages in queue */
               msglen_t        msg_qbytes; /* Maximum # of bytes in queue */
               pid_t           msg_lspid;  /* PID of last msgsnd(2) */
               pid_t           msg_lrpid;  /* PID of last msgrcv(2) */
           };

信号量:

           struct semid_ds {
               struct ipc_perm sem_perm;  /* Ownership and permissions */
               time_t          sem_otime; /* Last semop time */
               time_t          sem_ctime; /* Creation time/time of last
                                             modification via semctl() */
               unsigned long   sem_nsems; /* No. of semaphores in set */
           };

 我们不难发现,这三种IPC资源的数据结构中都包含了一个结构体ipc_perm,这就需要我们思考了,为什么要这么设计呢?跟着我的脚步往下走吧。

 上图是在Linux内核中管理System V IPC的部分,接下来我将依照这个图来进行讲解。

(二)IPC 命名空间

在Linux内核中存在一个IPC命名空间,它是一种用于隔离不同进程间通信资源的机制。IPC命名空间允许在同一主机上创建多个独立的IPC资源集合,每个 IPC 命名空间都有自己的信号量、消息队列和共享内存等 IPC 对象。

通过IPC命名空间,可以实现不同进程之间的通信资源隔离,避免不同进程之间的通信资源相互干扰。

IPC命名空间里面用struct ipc_ids的结构体数组来管理各种IPC资源,该结构体数组中的每一个元素都代表一个IPC资源,比如ids[0]可能代表信号量,ids[1]可能代表消息队列等。

struct ipc_namespace{
    atomic_t count; 
    struct ipc_ips ids[3];
    ......
};

(三)ipc_ips结构体

struct ipc_ids结构体内容如下

struct ipc_ids {
    struct ipc_id_ary *entries;
    int in_use;
    int max_id;
    int seq;
    struct ipc_id_ary *free;
    struct ipc_id_ary *in_use_next;
    struct ipc_id_ary *in_use_prev;
};

  • entries:存储 IPC 对象信息的数组,每个元素是一个 ipc_id_ary 结构体,用于存储特定类型的 IPC 对象的 id。
  • in_use:当前已经被使用的 IPC 对象数量。
  • max_id:当前 IPC 对象的最大 id。
  • seq:IPC 对象的序列号。
  • free:空闲的 ipc_id_ary 结构体链表,用于存储可以被重用的 IPC 对象 id。
  • in_use_next 和 in_use_prev:指向已经被使用的 ipc_id_ary 结构体的链表的下一个和上一个元素。

(四)ipc_id_ary结构体

 struct ipc_id_ary结构体内容如下:

struct ipc_id_ary {
    struct ipc_ids *ids;
    int in_use;
    int seq;
    struct kern_ipc_perm *p[IPCID_ARRAY_ENTRIES];
};
  • ids:指向包含该 ipc_id_ary 结构体的 ipc_ids 结构体的指针,用于确定所属的 IPC 对象类型。
  • in_use:表示该 ipc_id_ary 结构体当前是否被使用。
  • seq:IPC 对象的序列号。
  • p:一个长度为 IPCID_ARRAY_ENTRIES 的指针数组,用于存储指向 kern_ipc_perm 结构体的指针。kern_ipc_perm 结构体包含了 IPC 对象的权限信息等。

(五)kern_ipc_perm结构体

  kern_ipc_perm结构体内容如下:

struct kern_ipc_perm {
    key_t key;              // IPC 对象的键
    kuid_t uid;             // 拥有者的用户 ID
    kgid_t gid;             // 拥有者的组 ID
    kuid_t cuid;            // 创建者的用户 ID
    kgid_t cgid;            // 创建者的组 ID
    umode_t mode;           // 权限模式
    unsigned int seq;       // 序列号
};

(六)操作系统对IPC资源是如何管理的

可以发现,kern_ipc_perm跟共享内存、消息队列以及信号量中的ipc_perm的内容一致。

 现在我们可以对操作系统如何管理IPC资源来进行总结了。

设计者通过先描述,再组织的思想将各种IPC资源通过结构体数组的数据结构来进行管理,所以对IPC资源的管理就变成了对数组的增删查改。

接下来我将通过 操作系统是如何查找一个特定的IPC对象(这里我以消息量为例子)的权限信息的,来讲解IPC管理。

  1. 用户进程传递IPC对象的唯一标识符给系统,系统根据这个标识符进行查找。

    系统使用IPC对象的标识符作为索引,在全局的ipc_ids数组中进行查找。
  2. 系统根据IPC对象的标识符,在全局的ipc_ids数组中查找到对应的ipc_ids结构体,获取IPC对象的全局序列号。

    系统根据IPC对象的标识符计算出在ipc_ids数组中的位置,获取对应的ipc_ids结构体。
  3. 在ipc_ids结构体中的entries数组中,根据IPC对象的全局序列号找到对应的ipc_id_ary结构体。

    系统根据IPC对象的全局序列号,在entries数组中查找对应的ipc_id_ary结构体。
  4. 在ipc_id_ary结构体中,根据IPC对象的全局序列号和局部序列号,通过p指针数组找到要查找的IPC对象的位置。

    系统根据IPC对象的全局序列号和局部序列号,在p指针数组中找到对应的IPC对象的位置。
  5. 最终在kern_ipc_perm *p数组中找到了目标IPC对象的位置,可以对该IPC对象进行操作。

    系统根据在ipc_id_ary结构体中找到的位置,定位到kern_ipc_perm *p数组中对应的IPC对象。

通过以上步骤,系统可以根据用户传递的IPC对象的唯一标识符,通过一系列的查找和计算,最终定位到系统中具体的IPC对象,确保进程可以安全地访问和操作IPC资源。这种查找过程涉及到对全局数据结构的索引和计算,以及多层的查找和定位操作。

而最后找到的kern_ipc_perm结构体虽然和三种IPC方式中的ipc_perm结构体名称不同,但其内容都是相同的,操作系统会利用类型转换,通过kern_ipc_perm结构体就可以访问其他三种IPC方式的结构体了,这就类似于一种多态的思想,通过父类指针,访问子类。

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

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

相关文章

县供电公司员工向媒体投稿发文章用亲身经历告诉你并不难

在县供电公司的日子里,我肩负着一项至关重要的使命——信息宣传工作。这不仅仅是一份职责,更是连接公司与外界的桥梁,通过新闻稿件传递我们的声音,展示我们的成果。然而,回忆起刚刚踏入这个领域的时光,那段经历至今让我感慨万千。 初涉投稿,步履维艰 刚接手这项工作时,我的投稿…

探索DeepSeek平台:新一代MoE模型的深度体验

简介 DeepSeek是一个创新的人工智能平台,它最近推出了其最新版本的模型——DeepSeek-V2 MoE(Mixture of Experts)。这个平台不仅提供了一个交互式的聊天界面,还提供了API接口,让用户可以更深入地体验和利用这一先进的…

全体模型师请做好日入过万的准备!3D模型库海量资源,老子云平台免费用

在数字化的大背景下,3D转型已然成为了多行业关注的重点战略版块。无论是科技、金融、互联网、化工、建筑等等各个行业都在加速布局,3D手段会成为下一个重要的技术风口。也正因如此,3D市场潜能巨大,并且3D需求每年都在暴涨&#xf…

3d中如何对模型粉碎处理?---模大狮模型网

在3D建模和动画设计中,模型粉碎处理是一种引人注目的效果,可以为场景增添动态和震撼的视觉效果。无论是用于电影特效、游戏设计还是虚拟现实项目,都可以通过模型粉碎处理来创造出引人入胜的场景。本文将介绍如何在3D中轻松实现模型粉碎处理&a…

本地连接服务器Jupyter【简略版】

首先需要在你的服务器激活conda虚拟环境: 进入虚拟环境后使用conda install jupyter命令安装jupyter: 安装成功后先不要着急打开,因为需要设置密码,使用jupyter notebook password命令输入自己进入jupyter的密码: …

Windows端之Python3.9及以上高版本工程打包得到的exe逆向工程解包得到pyc文件进而得到py文件的流程实现

参考来自 【python逆向 pyc反编译】python逆向全版本通杀_python反编译pyc-CSDN博客https://blog.csdn.net/zjjcxy_long/article/details/127346296Pyinstaller打包的exe之一键反编译py脚本与防反编译_pyinstaller防止反编译-CSDN博客https://blog.csdn.net/as604049322/artic…

「网络流 24 题」魔术球 【最小路径覆盖】

「网络流 24 题」魔术球 注意这里的球是依次放置&#xff0c;也就是说如果当前放到第 i i i 号球&#xff0c;那么 1 → i − 1 1 \rarr i - 1 1→i−1 号球都已经放好了&#xff0c;否则可以放无数个球 思路 首先我们对于 i < j 且 i j 完全平方数 i < j 且 i j…

在思科和华为上实现两个主机A,B A能ping通B,B不能ping通A

1.华为实验的topo如下 常规状态下任意两台主机都是可以ping通的 此时的需求是PC4能ping通PC2和PC3但是PC2和PC3不能ping通PC4 这里需要用到ACL策略 在接口上调用 验证&#xff1a; PC4能ping通PC2和PC3 PC2和PC3不能ping通PC4 2.思科类似 正常情况下是都能互相ping通 加上ac…

嵌入式Linux的QT项目CMake工程模板分享及使用指南

在嵌入式linux开发板上跑QT应用&#xff0c;不同于PC上的开发过程。最大的区别就是需要交叉编译&#xff0c;才能在板子上运行。 这里总结下嵌入式linux环境下使用CMake&#xff0c;嵌入式QT的CMake工程模板配置及如何使用&#xff0c;分享给有需要的小伙伴&#xff0c;有用到的…

Github的使用教程(下载和上传项目)

根据『教程』一看就懂&#xff01;Github基础教程_哔哩哔哩_bilibili 整理。 1.项目下载 1&#xff09;直接登录到源码链接页或者通过如下图的搜索 通过编程语言对搜索结果进一步筛选。 2&#xff09;红框区为项目的源代码&#xff0c;README.md &#xff08;markdown格式&…

企业如何用数字化为预提摊销业务赋能?

对于企业来说&#xff0c;想要实现系统化、智能化、自动化的预提摊销管理&#xff0c;需要做足哪些功课&#xff1f;常见场景下的业务难题又该如何破解&#xff1f;今天胜意科技就给大家介绍一下&#xff0c;企业如何通过数字化手段搞定预提摊销业务难题。 一、预提摊销痛点 在…

Spring后端参数校验——自定义校验方式(validation)

文章目录 开发场景技术名词解释——Spring Validation自定义校验 技术细节小结1.实体参数校验2.自定义校验 完整代码 开发场景 业务场景&#xff1a;新增文章 基本信息 请求路径&#xff1a;/article 请求方式&#xff1a;POST 接口描述&#xff1a;该接口用于新增文章(发布文…

小样本学习

小样本学习的概念最早从计算机视觉(computer vision)[8]领域兴起, 近几年受到广泛关注, 在图像分类任务中已有很多性能优异的算法模型[9-11].但是在自然语言处理领域(natural language processing)[12]的发展较为缓慢, 原因在于图像和语言特性不同.图像相比文本更为客观, 所以当…

学习方法的重要性

原贴&#xff1a;https://www.cnblogs.com/feily/p/13999204.html 原贴&#xff1a;https://36kr.com/p/1236733055209095 1、 “一万小时定律”的正确和误区 正确&#xff1a; 天才和大师的非凡&#xff0c;不是真的天资超人一等&#xff0c;而是付出了持续不断的努力&…

C++:菱形继承与菱形虚拟继承

一、菱形继承 单继承&#xff1a;一个子类只有一个直接父类时称这个继承关系为单继承 多继承&#xff1a;一个子类有两个或以上直接父类时称这个继承关系为多继承 菱形继承&#xff1a;菱形继承是多继承的一种特殊情况&#xff0c;派生类继承自两个间接基类&#xff0c;而这…

MVC与MVVM架构模式

1、MVC MVC&#xff1a;Model-View-Controller&#xff0c;即模型-视图-控制器 MVC模式是一种非常经典的软件架构模式。从设计模式的角度来看&#xff0c;MVC模式是一种复合模式&#xff0c;它将多个设计模式结合在一种解决方案中&#xff0c;从而可以解决许多设计问题。 MV…

C++缺省参数、函数重载、引用

一、缺省参数 1.1缺省参数概念 缺省参数是声明或定义函数时为函数的参数指定一个缺省值。在调用该函数时&#xff0c;如果没有指定实参则采用该形参的缺省值&#xff0c;否则使用指定的实参。 void func(int n 0) {cout << n << endl; }int main() {func();func…

营销H5测试综述

H5页面是营销域最常见的一种运营形式&#xff0c;业务通过H5来提供服务&#xff0c;可以满足用户对于便捷、高效和低成本的需求。H5页面是业务直面用户的端点&#xff0c;其质量保证工作显得尤为重要。各业务的功能实现具有通用性&#xff0c;相应也有共性的测试方法&#xff0…

【C语言】字符函数和字符串函数--超详解

前言&#xff1a; 在编程的过程中&#xff0c;我们经常要处理字符和字符串&#xff0c;为了⽅便操作字符和字符串&#xff0c;C语⾔标准库中提供了 ⼀系列库函数&#xff0c;接下来我们就学习⼀下这些函数。 1. 字符分类函数 C语⾔中有⼀系列的函数是专⻔做字符分类的&#…

Java 线程池之 ThreadPoolExecutor

Java线程池&#xff0c;特别是ThreadPoolExecutor&#xff0c;是构建高性能、可扩展应用程序的基石之一。它不仅关乎效率&#xff0c;还直接关系到资源管理与系统稳定性。想象一下&#xff0c;如果每来一个请求就创建一个新的线程&#xff0c;服务器怕是很快就要举白旗了。而Th…
最新文章