共享内存是一种最为高效的进程间通信方式,进程可以直接读写内存, 而不需要任何数据的拷贝
共享内存在内核空间创建, 可以被进程映射到用户空间访问
由于多个进程可同时访问共享内存 , 因此需要同步和互斥机制配合使用
共享内存的使用步骤
创建/打开共享内存
映射共享内存, 即把指定的共享内存映射到进程的地址空间用于访问
读写共享内存
撤销共享内存映射
删除共享内存对象
共享内存创建
#include<sys/ipc.h>
#include<sys/shm.h>
int shmget(key_t key, int size, int shmflg)
成功返回共享内存的id 失败返回EOF
key 和共享内存关联得key, IPC_PAIVATE或ftok生成
shmflg 共享内存的标志位 IPC_CREAT|0666
共享内存的映射
#include <sys/ipc.h.>
#include <sys/shm.h>
void *shmat(int shmid, const void *shmaddr, int shmflg)
成功返回映射后的地址, 失败返回(void *)-1
shmid 要映射的共享内存id
shmaddr 映射后的地址 NULL表示由系统自动映射
shmflg 标志位 0表示可读写 SHM_RDONLY表示只读
共享内存读写
通过指针访问共享内存, 指针类型取决于共享内存中存放的数据类型
共享内存撤销映射
#include <sys/ipc.h>
#include <sys/shm.h>
int shmdt(void *shmaddr);
成功返回0 失败返回EOF
不使用共享内存时 应及时撤销映射
进程结束时 自动撤销
共享内存控制
#include <sys/ipc.h>
#include <sys/shm.h>
int shmctl(int shmid, int cmd, struct shmid_ds *buf)
成功返回0 失败返回EOF
shmid 要操作的共享内存的id
cmd 要执行的操作 IPC_STAT(保存共享内存的属性) IPC_SET(设置共享内存的属性)
IPC_RMID(删除共享内存的属性, 使用时不需要第三个参数)
buf 保存或设置共享内存属性的地址
注意事项
每块共享内存大小有限制
ipcs -l 列举一些共享内存的信息
cat /proc/sys/kernel/shmmax 可在这个文件中修改这些信息
共享内存删除的时间点
shmctl(shmid, IPC_RMID, NULL) 添加删除标记(只是标记 不会立马删除)
nattach 变成0时 真正被删除 不为零表示还有进程在使用共享内存