5.3 Linux 应用开发 进程(三)
一、共享内存(Shared Memory)
共享内存是最快的 IPC 方式,它将一段物理内存区域映射到不同进程的虚拟地址空间,让多个进程直接通过指针读写内存,无需数据拷贝。
1. 内存映射(mmap)
直接将文件或设备映射到进程虚拟内存中,实现进程间通信。
函数:
void *mmap(void *addr, size_t length, int port, int flags, int fd, off_t offset); // 参数详解: // addr:指定映射地址;通常填 NULL,由系统自动选择。 // length:映射字节数(必须 > 0),从 offset 开始计算。 // port(访问权限): // PROT_READ:可读 // PROT_WRITE:可写 // PROT_EXEC:可执行 // PROT_NONE:不可访问 // flags(标志位): // MAP_SHARED:共享映射,数据会同步到文件,其他进程可见。 // MAP_PRIVATE:私有映射,写时复制,修改不影响原文件。 // MAP_ANONYMOUS:匿名映射,仅用于亲缘进程通信,不需要文件支持。 // fd:文件描述符;匿名映射填 -1。 // offset:文件偏移量,必须页对齐,通常为 0。 // 返回值:成功返回映射区地址;失败返回 MAP_FAILED。
解除映射:
int munmap(void *addr, size_t length); // 成功返回0,失败返回-1
2. 系统 V 共享内存(shm)
通过内核对象管理的共享内存段,支持非亲缘进程通信。
使用步骤:
- 步骤 1:生成 Key(ftok):将文件路径和项目 ID 转换为 System V IPC Key。
key_t ftok(const char *path, int proj_id); // path:可访问的文件路径。 // proj_id:项目 ID(0~255)。 // 作用:生成唯一的 Key,用于关联共享内存段。
- 步骤 2:创建 / 打开共享内存(shmget)
int shmget(key_t key, int size, int shmflag); // 参数: // key:由 ftok 生成,或 IPC_PRIVATE(仅用于亲缘进程)。 // size:共享内存大小(字节),创建时指定,读取时填 0。 // shmflag:权限标志 // IPC_CREAT:创建,如果不存在。 // IPC_EXCL:与IPC_CREAT连用,若已存在则报错。 // 权限掩码:如 0666。 //返回值:成功返回共享内存标识符(shmid);失败返回 -1。
- 步骤 3:映射到用户空间(shmat):将内核中的共享内存段映射到进程虚拟地址空间。
void *shmat(int shmid, const void *shmaddr, int shmflag); // 参数: // shmid:shmget 返回的标识符。 // shmaddr:指定映射地址;填 NULL 由系统自动分配。 // shmflag:权限 // 0:可读可写 // SHM_RDONLY:只读 // 返回值:成功返回映射后的地址;失败返回 (void *)-1。
- 步骤 4:解除映射(shmdt):断开进程与共享内存的关联(不会删除内核对象)。
int shmdt(void *shmaddr); // 成功返回0,失败返回-1
- 步骤 5:删除共享内存对象(shmctl):从内核中删除共享内存段(当所有进程解除映射后才生效)。
int shmctl(int shmid, int cmd, struct shmid_ds *buf); // 参数: // shmid:共享内存标识符。 // cmd:控制命令 // IPC_RMID:标记删除共享内存段(最常用)。 // buf:设置 / 获取信息;删除时填 NULL。 // 返回值:成功返回 0;失败返回 -1。
二、消息队列(Message Queue)
消息队列是内核维护的链式队列,通过 msqid_ds 结构体管理,包含 msg_first(指向第一个消息)和 msg_last(指向最后一个消息)。每个消息包含 4 个部分:next(链表指针)、type(消息类型)、length(长度)、data(数据)。
特性:消息被读取后会从队列中移除,支持按类型选择性读取,可用于非亲缘进程通信。
1. 核心函数详解:
(1) 打开 / 创建消息队列 msgget():
int msgget(key_t key, int flag); // 参数说明: // key:由 ftok() 生成的 IPC 键值,用于唯一标识消息队列 // flag:权限标志,常用 IPC_CREAT | 0666(有则打开,无则创
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
C++/嵌入式开发 秋招面经 文章被收录于专栏
一名985硕,在25年秋招中斩获多个C++/嵌入式开发Offer。本专栏将分享我的面经,涵盖C/C++、操作系统、计算机网络、ARM体系与架构、Linux应用/驱动开发、Qt、通信协议及开发工具链等核心内容。
查看11道真题和解析