【Linux进程间通信:共享内存】为什么共享内存的 key 值由用户设置

🎬 个人主页艾莉丝努力练剑
专栏传送门 :《C语言》《数据结构与算法》《C/C++干货分享&学习过程记录
Linux操作系统编程详解》《笔试/面试常见算法:从基础到进阶》《Python干货分享

⭐️为天地立心,为生民立命,为往圣继绝学,为万世开太平


🎬 艾莉丝的简介:


文章目录

  • [1 ~> 为什么共享内存的 key 值由用户设置?](#1 ~> 为什么共享内存的 key 值由用户设置?)
    • [1 让不相关的进程找到同一个共享资源](#1 让不相关的进程找到同一个共享资源)
    • [2 实现命名资源的协作模型](#2 实现命名资源的协作模型)
    • [3 避免冲突和实现权限控制](#3 避免冲突和实现权限控制)
    • [4 灵活性与系统自动分配的权衡](#4 灵活性与系统自动分配的权衡)
  • [2 ~> 总结](#2 ~> 总结)
  • 结尾


在 System V IPC(进程间通信)机制中,共享内存、消息队列和信号量都依赖一个名为 key 的整数值来标识资源。很多初学者会困惑:为什么这个 key 必须由用户指定,而不是操作系统自动生成一个简单的 ID?本文将深入探讨其背后的设计哲学和实际用途。

1 ~> 为什么共享内存的 key 值由用户设置?

1 让不相关的进程找到同一个共享资源

这是 最根本的原因 。共享内存的主要目的是让多个 没有亲缘关系 的进程(例如一个数据库服务和一个管理工具)访问同一块物理内存。

  • 如果 ID 由内核随机生成 :假设每次创建共享内存时,内核随机分配一个 ID(比如 12345)。另一个进程如何知道这个 12345 对应的是哪块内存?除非通过复杂的带外通信把随机 ID 传递过去,这显然不现实。
  • 使用用户约定的 Key :通过一个双方 事先约定 的、固定的、在整个系统中唯一的 key(例如 0x123456,或通过 ftok() 函数基于文件路径生成的 key),两个进程可以各自调用 shmget(key, ...)。内核看到这个 key 就能确定它们想要访问的是同一块共享内存。

类比key 就像公共图书馆的 索书号 。如果图书馆每次随机给书编号,你想找《红楼梦》就完全不知道该找哪个号。但若约定《红楼梦》的索书号是 I242.4/1,无论谁去查这个号,都能找到那本书。

2 实现命名资源的协作模型

System V IPC 的设计哲学是 "命名资源"

  • 进程 A 通过一个 key 创建(IPC_CREAT)了一块共享内存。
  • 进程 B 知道这个 key,它不需要重新创建,只需"获取"即可。

如果 key 由内核自动分配,进程 B 就失去了一个固定的"名字"去查找这块内存。虽然我们可以通过文件或管道传递内核分配的 ID,但这增加了复杂度,而且不够健壮。直接在代码或配置文件中约定一个 key 是最直接的"握手"方式。

3 避免冲突和实现权限控制

用户设置 key 也意味着对资源命名的控制:

  • 防止冲突 :不同的应用程序团队可以协商使用不同的 key 范围,或者使用 ftok() 函数基于一个特定的文件路径(通常是程序自己的配置文件或可执行文件)和一个项目 ID 来生成 key。由于不同程序使用的文件路径不同,生成的 key 重复的概率就非常低。
    • ftok() 典型用法:

      c 复制代码
      key_t key = ftok("/tmp/myserver.conf", 1);

只要文件路径和 ID 不变,生成的 key 就不变。

权限结合:创建共享内存时,不仅要指定 key,还要指定权限(如 0666)。内核将 key 和权限信息绑定在该 IPC 对象上。如果 key 是自动生成的,那么权限的管理也会变得混乱。

4 灵活性与系统自动分配的权衡

有人可能会问:"如果我不想手动管理 key,想让系统自动分配一个给我用,行不行?"

答案是:可以。

  • System V IPC 提供了一个特殊值:IPC_PRIVATE

    • 当你在 shmget() 中传入 key = IPC_PRIVATE 时,内核会保证创建一个全新的共享内存段,并返回一个唯一的ID

    • 但是 ,因为 keyIPC_PRIVATE,其他进程无法通过 key 找到它。它通常仅用于有亲缘关系的进程 (比如父子进程)。父进程创建共享内存后,通过fork()子进程继承了父进程的资源描述符,可以直接使用返回的shmid

这正好从反面证明了用户设置 key 的必要性:

  • 当你需要无关进程 通信时,IPC_PRIVATE无能为力,你必须依靠一个约定的、用户设置的key来作为通信的锚点。

2 ~> 总结

共享内存的 key 由用户设置,本质上是为了在操作系统的全局范围内,提供一个稳定的、众所周知的、用于定位和协商共享资源的命名机制。它让完全独立的进程可以通过一个约定的"暗号"找到对方,共同访问同一块物理内存------这是实现进程间通信的基础。


结尾

uu们,本文的内容到这里就全部结束了,艾莉丝在这里再次感谢您的阅读!

结语:希望对学习Linux相关内容的uu有所帮助,不要忘记给博主"一键四连"哦!

往期回顾

【Linux:文件】进程间通信

🗡博主在这里放了一只小狗,大家看完了摸摸小狗放松一下吧!🗡 ૮₍ ˶ ˊ ᴥ ˋ˶₎ა

相关推荐
2301_813599555 小时前
Go语言怎么做秒杀系统_Go语言秒杀系统实战教程【实用】
jvm·数据库·python
JZC_xiaozhong9 小时前
数据不互通、审批慢?企业多系统智能协同与流程自动化解决方案
运维·自动化·流程管理·流程自动化·数据集成与应用集成·流程监控·流程可视化设计
爱学习的小囧9 小时前
ESXi 8.0 原生支持 NVMe 固态硬盘吗?VMD 配置详解教程
linux·运维·服务器·esxi·esxi8.0
NCIN EXPE9 小时前
redis 使用
数据库·redis·缓存
MongoDB 数据平台9 小时前
为编码代理引入 MongoDB 代理技能和插件
数据库·mongodb
lUie INGA10 小时前
在2023idea中如何创建SpringBoot
java·spring boot·后端
极客on之路10 小时前
mysql explain type 各个字段解释
数据库·mysql
代码雕刻家10 小时前
MySQL与SQL Server的基本指令
数据库·mysql·sqlserver
lThE ANDE10 小时前
开启mysql的binlog日志
数据库·mysql
坚持就完事了10 小时前
Linux中的变量
linux·运维·服务器