【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 lastmodification 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 lastmodification 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 lastmodification 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;             // 拥有者的用户 IDkgid_t gid;             // 拥有者的组 IDkuid_t cuid;            // 创建者的用户 IDkgid_t cgid;            // 创建者的组 IDumode_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.mzph.cn/pingmian/8579.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

视频提取gif怎么制作?试试这个网站一键转换

通过把视频转换成gif动图的操作能够更加方便的在各种平台上分享和传播。相较于视频,gif图片具有较小的文件体积,gif动图能够快速的加载播放,不需要等待就能快速欣赏。很适合从事新媒体之类的小伙伴,可以用来做展示、宣传等。想要实…

刷题训练之模拟

> 作者:დ旧言~ > 座右铭:松树千年终是朽,槿花一日自为荣。 > 目标:熟练掌握模拟算法。 > 毒鸡汤:学习,学习,再学习 ! 学,然后知不足。 > 专栏选自:刷题训…

vue 路由url中去掉#

修改前效果 想要去掉/# 如何实现? 1、typeScript中去掉url中# 找到项目中的router/index.ts-----------去掉createWebHashHistory中的Hash 将createWebHashHistory修改为createWebHistory 2、javaScript中去掉url中# 找到项目中的router/index.js-----------添加…

基于Nios-II的流水灯

基于Nios-II的流水灯 一、Qsys设计(一)新建项目(二)Platfrom Designer(三)设置时钟主频(四)添加Nios-II Processor并设置(五)添加JTAG并配置(六&a…

做外贸用什么邮箱比较好?

外贸公司在推进公司业务时需要频繁进行跨国沟通,选择一款专业且功能强大的企业邮箱作为业务沟通工具至关重要。外贸企业邮箱需要满足5个基本内容,国际收发能力、安全稳定性、专业形象展示、功能完备性、客户服务与技术支持。本文将探讨做外贸时适合使用的…

Tkinter组件:Checkbutton

Tkinter组件:Checkbutton Checkbutton(多选按钮)组件用于实现确定是否选择的按钮。Checkbutton 组件可以包含文本或图像,你可以将一个 Python 的函数或方法与之相关联,当按钮被按下时,对应的函数或方法将被…

游戏全自动打金搬砖,单号收益300+ 轻松日入1000+

详情介绍 游戏全自动打金搬砖,单号收益300左右,多开收益更多,轻松日入1000 可矩阵操作。 项目长期稳定,全自动挂机无需人工操作,小白,宝妈,想做副业的都可以。

elementui+vue通过下拉框多选字段进行搜索模糊匹配

从字典中选择的值为["01","03"],在最开始的时候进行的处理是类似于表单提交的时候将json对象转换成了String类型 nature:["01","03"] this.queryParams.nature JSON.stringify(this.queryParams.nature); mapper层 <if test&quo…

springboot+vue+mybatis图书推荐管理系统的设计与实现+PPT+论文+讲解+售后

随着我国经济的高速发展与人们生活水平的日益提高&#xff0c;人们对生活质量的追求也多种多样。尤其在人们生活节奏不断加快的当下&#xff0c;人们更趋向于足不出户解决生活上的问题&#xff0c;图书推荐管理系统展现了其蓬勃生命力和广阔的前景。与此同时&#xff0c;为解决…

亲测快捷高效的编写测试用例方法

前言 测试用例是任何测试周期的第一步&#xff0c;对任何项目都非常重要。如果在此步骤中出现任何问题&#xff0c;则在整个软件测试过程中都会扩大影响。如果测试人员在创建测试用例模板时使用正确的过程和准则&#xff0c;则可以避免这种情况。 在本篇文章中将分享一些简单而…

Shell变成规范与变量

目录 1. Shell脚本 1.1 Shell脚本概述 1.2 Shell的作用 1.3 Shell脚本的构成 2. 重定向与管道操作 2.1 交互式硬件设备 ​ 2.2 重定向操作 3. shell变量 3.1 自定义变量 3.2 变量的作用范围​编辑 3.3 整数变量的运算 4. 环境变量 4.1 特殊的Shell变量 4.2 只读变…

鸿蒙开发接口Ability框架:【@ohos.application.formProvider (FormProvider)】

FormProvider FormProvider模块提供了卡片提供方相关接口的能力&#xff0c;包括更新卡片&#xff0c;设置卡片更新时间&#xff0c;获取卡片信息&#xff0c;请求发布卡片等。 说明&#xff1a; 本模块首批接口从API version 8开始支持。后续版本的新增接口&#xff0c;采用上…

机器人系统可以支持对接人工系统吗?

​ 随着科技的飞速发展&#xff0c;机器人系统在各行各业都扮演着越来越重要的角色。它们可以高效地处理大量数据&#xff0c;执行繁琐的任务&#xff0c;甚至在某些领域超越了人类的能力。然而&#xff0c;机器人系统也有其局限性&#xff0c;特别是在处理复杂的人际交往…

【Qt 开发基础体系】Qt信号与槽机制

文章目录 1.Qt 信号与槽机制原理&#xff08;Signal & Slot&#xff09;2. QObject 类 connect 的介绍3. 信号与槽机制连接方式4. 信号和槽机制优势及其效率&#xff1a;3. 信号与槽机制应用 1.Qt 信号与槽机制原理&#xff08;Signal & Slot&#xff09; &#x1f42…

Kafka---总结篇

kafka架构 主要概念 broker: 存储消息的机器 控制器controller &#xff08;1&#xff09;使用zookeeper&#xff0c; 除了提供一般的broker功能之外&#xff0c;还负责选举分区首领。通过在zookeepr中创建一个名为 /controller的临时节点称为 controller。每个选出的contro…

C# 和 Qt 相比的一些优势

C# 和 Qt 都是流行的软件开发工具&#xff0c;它们各自具有不同的优势&#xff0c;适用于不同的开发场景。以下是 C# 和 Qt 相比的一些优势。相比之下&#xff0c;Qt 也有其独特的优势&#xff0c;特别是在跨平台 GUI 应用程序开发方面。然而&#xff0c;C# 的这些优势使得它在…

Ubuntu22.04下安装kafka_2.11-0.10.1.0并运行简单实例

目录 一、版本信息 二、安装Kafka 1.将Kafka安装包移到下载目录中 2.下载Spark并确保hadoop用户对Spark目录有操作权限 三、启动Kafka并测试Kafka是否正常工作 1.启动Kafka 2.测试Kafka是否正常工作 一、版本信息 虚拟机产品&#xff1a;VMware Workstation 17 Pro 虚…

软件测试实战项目(含电商、银行、APP等)

&#x1f345; 视频学习&#xff1a;文末有免费的配套视频可观看 &#x1f345; 关注公众号【互联网杂货铺】&#xff0c;回复 1 &#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 今天给大家带来几个软件测试项目的实战总结及经验&#xff0c;适…

初学python记录:力扣1652. 拆炸弹

题目&#xff1a; 你有一个炸弹需要拆除&#xff0c;时间紧迫&#xff01;你的情报员会给你一个长度为 n 的 循环 数组 code 以及一个密钥 k 。 为了获得正确的密码&#xff0c;你需要替换掉每一个数字。所有数字会 同时 被替换。 如果 k > 0 &#xff0c;将第 i 个数字用…

JUC下的ScheduledThreadPoolExecutor详解

ScheduledThreadPoolExecutor是Java并发编程框架中一个强大且灵活的线程池实现&#xff0c;专为定时与周期性任务而设计。作为ThreadPoolExecutor的子类&#xff0c;它不仅继承了线程池管理的高效与灵活性&#xff0c;还内置了基于优先级队列的延迟任务调度机制&#xff0c;支持…