POSIX IPC 与 System V IPC 内核实现位置对比(基于 2.6.12)
概述
- POSIX 消息队列 在
ipc/目录, 而 POSIX 共享内存 在mm/目录的原因 - System V 共享内存 在
ipc/目录, 而 POSIX 共享内存 在mm/目录的原因
理解这些设计决策有助于理解 Linux 内核的模块化架构和不同 IPC 机制的设计理念.
POSIX IPC 的实现位置差异
POSIX 消息队列在 ipc/ 目录的原因
-
功能定位: 消息队列是典型的 IPC 机制, 需要管理消息的发送、接收、排队、优先级等逻辑, 这些功能与 System V 消息队列(
ipc/msg.c)高度相似 -
数据结构复用: 复用 System V 消息队列的
msg_msg结构, 消息管理逻辑相似 -
独立性: 虽然通过 mqueue 文件系统实现, 但核心的消息队列管理逻辑(发送/接收/优先级排序)是独立的 IPC 功能, 不依赖内存管理子系统
-
代码组织: 与 System V IPC 放在同一目录便于代码管理和维护
POSIX 共享内存在 mm/ 目录的原因
-
功能定位: POSIX 共享内存本质上是内存映射功能, 核心是页管理、虚拟地址映射、VMA 管理等, 这些都属于内存管理范畴
-
依赖关系: POSIX 共享内存通过
shm_open+mmap实现, 核心依赖mm/mmap.c的映射机制和mm/shmem.c的页管理 -
实现方式:
shm_open创建 shmem 文件(在mm/shmem.c中实现)mmap将文件映射到进程地址空间(在mm/mmap.c中实现)- 页的分配、换入换出都在内存管理子系统中处理
-
代码复用: shmem 文件系统不仅用于 POSIX 共享内存, 还用于匿名内存映射、tmpfs 等, 是内存管理子系统的一部分
POSIX IPC 对比总结
| 特性 | POSIX 消息队列 | POSIX 共享内存 |
|---|---|---|
| 核心功能 | 消息管理、排队、优先级 | 内存映射、页管理 |
| 主要依赖 | IPC 框架、文件系统 | 内存管理子系统 |
| 数据结构 | mqueue_inode_info、msg_msg | shmem_inode_info、vm_area_struct |
| 系统调用 | mq_open/mq_send/mq_receive | shm_open + mmap/munmap |
| 实现位置 | ipc/mqueue.c | mm/shmem.c + mm/mmap.c |
| 与 System V 的关系 | 功能相似, 可类比 | 实现方式不同, 但都使用 shmem |
结论: POSIX 消息队列放在 ipc/ 目录是因为它是 IPC 机制, 而 POSIX 共享内存放在 mm/ 目录是因为它是内存管理功能. 这种组织方式符合内核的模块化设计原则: 功能相近的代码放在一起, 依赖关系清晰的代码放在被依赖的模块中.
System V vs POSIX 共享内存的实现位置差异
这是一个更深层次的设计问题, 关键在于两者对 IPC 框架的依赖关系不同.
System V 共享内存在 ipc/ 目录的原因
1. 依赖 IPC 框架
System V 共享内存是 IPC 框架的一部分, 必须使用 ipc/util.c 提供的功能:
- ID 管理: 通过
ipc_addid()将共享内存段安装到 IPC ID 表(shm_ids) - 键值查找: 通过
ipc_findkey()根据键值(key)查找共享内存段 - 权限检查: 通过
ipcperms()检查访问权限 - 对象锁定: 通过
ipc_lock()/ipc_unlock()保护并发访问 - 删除管理: 通过
ipc_rmid()从 IPC 表中移除
2. 数据结构设计
shmid_kernel 结构包含 kern_ipc_perm, 这是 IPC 框架的核心结构:
// include/linux/shm.h
struct shmid_kernel {
struct kern_ipc_perm shm_perm; // IPC 权限/键值/锁 ← 关键!
struct file *shm_file; // 关联的 shmem 文件
int id; // 内部 ID (用于 IPC 表索引)
unsigned long shm_nattch; // 当前附加次数
unsigned long shm_segsz; // 段大小(字节)
// ...
};
3. 系统调用设计
System V 共享内存有独立的系统调用接口:
shmget(): 通过键值创建/查找, 返回 IPC IDshmat()/shmdt(): 通过 IPC ID 操作shmctl(): 通过 IPC ID 控制(删除/设置/查询)
4. 管理方式
使用 IPC ID 表管理, 与消息队列、信号量统一管理:
- 通过
ipcs -m查看所有共享内存段 - 通过
ipcrm -m删除共享内存段 - 在
/proc/sysvipc/shm中可见
5. 历史原因
System V IPC 是统一设计的, 消息队列、信号量、共享内存都使用相同的 IPC 框架.
POSIX 共享内存在 mm/ 目录的原因
1. 不依赖 IPC 框架
POSIX 共享内存完全独立于 IPC 框架:
- 不使用
ipc/util.c的任何功能 - 不使用 IPC ID 表
- 不使用键值(key)标识
- 不使用
kern_ipc_perm结构
2. 基于文件系统
POSIX 共享内存通过文件系统实现:
- 使用名字(name)标识, 如
/my_shm - 通过 VFS 路径查找, 不通过 IPC ID 表
- 在
/dev/shm文件系统中可见
3. 系统调用设计
POSIX 共享内存使用标准的文件系统 + 内存映射接口:
shm_open(): 创建/打开文件(类似open())mmap(): 映射文件到地址空间(标准内存映射)munmap(): 取消映射(标准内存映射)shm_unlink(): 删除文件(类似unlink())
4. 实现方式
直接使用内存管理子系统:
shm_open创建 shmem 文件(在mm/shmem.c中)mmap映射文件(在mm/mmap.c中)- 页管理、VMA 管理都在
mm/目录中
5. 设计理念
POSIX 共享内存遵循"一切皆文件"的设计:
- 共享内存对象就是文件
- 通过文件描述符操作
- 使用标准的文件系统权限模型
System V vs POSIX 共享内存对比
| 特性 | System V 共享内存 | POSIX 共享内存 |
|---|---|---|
| 依赖框架 | IPC 框架(ipc/util.c) | 无, 直接使用文件系统 |
| 标识方式 | 键值(key) + IPC ID | 名字(name) + 文件路径 |
| 查找方式 | IPC ID 表(ipc_findkey) | VFS 路径查找 |
| 数据结构 | shmid_kernel + kern_ipc_perm | shmem_inode_info + file |
| 系统调用 | shmget/shmat/shmdt/shmctl | shm_open + mmap/munmap/shm_unlink |
| 管理工具 | ipcs/ipcrm | ls/rm (文件系统) |
| 实现位置 | ipc/shm.c | mm/shmem.c + mm/mmap.c |
| 底层实现 | 都使用 shmem 文件系统 | 都使用 shmem 文件系统 |
实现路径对比
System V 共享内存
用户空间
↓ shmget(key, ...)
IPC 框架 (ipc/util.c)
↓ ipc_addid() → IPC ID 表
ipc/shm.c
↓ shmem_file_setup()
mm/shmem.c (底层实现)
POSIX 共享内存
用户空间
↓ shm_open(name, ...)
VFS 文件系统
↓ 路径查找
mm/shmem.c (直接实现)
↓ mmap()
mm/mmap.c (内存映射)
核心差异总结
System V 共享内存:
- 是"IPC 对象", 需要通过 IPC 框架管理
- 在 IPC 框架和 shmem 之间增加了一层抽象
- 使用键值和 IPC ID 标识
POSIX 共享内存:
- 是"文件对象", 通过文件系统管理
- 直接使用文件系统接口
- 使用名字和文件路径标识
共同点: 虽然两者底层都使用 shmem 文件系统, 但 System V 在 IPC 框架和 shmem 之间增加了一层抽象, 而 POSIX 直接使用文件系统接口.
总结
设计原则
Linux 内核的模块化设计遵循以下原则:
- 功能相近的代码放在一起: POSIX 消息队列与 System V 消息队列功能相似, 都放在
ipc/目录 - 依赖关系清晰的代码放在被依赖的模块中: POSIX 共享内存依赖内存管理子系统, 放在
mm/目录 - 框架依赖决定位置: System V 共享内存依赖 IPC 框架, 放在
ipc/目录; POSIX 共享内存不依赖 IPC 框架, 放在mm/目录
设计理念差异
- System V IPC: 统一的 IPC 框架, 所有 IPC 对象(消息队列、信号量、共享内存)都通过 IPC ID 表统一管理
- POSIX IPC: "一切皆文件"的现代设计, 通过文件系统接口实现, 更符合 Unix 哲学
实现位置总结
| IPC 机制 | 实现位置 | 原因 |
|---|---|---|
| System V 消息队列 | ipc/msg.c | IPC 框架的一部分 |
| System V 信号量 | ipc/sem.c | IPC 框架的一部分 |
| System V 共享内存 | ipc/shm.c | IPC 框架的一部分, 依赖 ipc/util.c |
| POSIX 消息队列 | ipc/mqueue.c | IPC 机制, 功能与 System V 消息队列相似 |
| POSIX 共享内存 | mm/shmem.c + mm/mmap.c | 内存管理功能, 不依赖 IPC 框架 |
这种组织方式体现了 Linux 内核的模块化设计: 每个模块负责自己的核心功能, 通过清晰的接口和依赖关系组织在一起.



被折叠的 条评论
为什么被折叠?



