共享内存
特性: 进程间最快的通信方式。
本质: 在物理内存上开辟一块内存空间,多个进程可以将同一块物理内存空间映射到自己的虚拟空间中,再通过自己的虚拟地址直接访问此空间,通过此方式实现数据的共享。
生命周期: 生命周期随着Linux系统内核变化,不会随着进程的退出而释放。需要重启系统内核或者手动释放,否则将一直存在于系统内核。
共享内存的操作流程:
1> 创建虚拟内存空间 ---- 在物理内存上开辟空间。
2> 进程将共享内存映射到自己的虚拟地址空间。
3> 对共享内存进行操作。
4> 不使用、解除虚拟空间和共享内存的联系。
5> 释放共享内存。
具体方法
1.创建共享内存
int shmget(key_t key, size_t size, int shmflg);
key: 内存中共享内存的标识符
size: 以内存页为单位进行分配(内存页大小一般为 4096 个字节)
shmflg: 对共享内存的操作(参数如下)
IPC_CREAT(存在则打开文件,不存在则创建文件,后面需要 | 文件权限)
IPC_CREAT | IPC_EXCL(存在则报错,不存在则创| 文件权限)
返回值: 成功返回一个非负整数---即共享内存的操作句柄
失败返回 -1
2. 将共享内存映射到自己的虚拟地址空间
void* shmat(int shmid, const void* shmaddr, int shmflg)
shmid : 共享内存的操作句柄
shmaddr: 共享内存映射到虚拟地址空间的首地址,通常置NULL
shmflg: 映射成功后对共享内存的操作(参数如下)
SHM_RDONLY(对共享内存的只读操作,前提是拥有读的权限)
0 (默认的读写操作)
返回值: 成功返回共享内存映射在虚拟地址空间的首地址
失败返回 -1
3.解除映射关系
int shmdt(const void* shmaddr)
shmaddr: 共享内存映射到虚拟地址空间的首地址
返回值:成功返回 0
失败返回 -1
4.释放共享内存空间
int shmctl(int chmid, int cmd, struct shmid_ds* buf)
chmid: 共享内存的操作句柄
cmd: 对共享内存的操作
IPC_RMID(删除参数)
buf: 用于获取/设置共享内存信息的结构,不适用则置NULL
返回值: 成功 0
失败 -1
几个常用查看/删除进程间通信信息的指令
1. ipcs: 用于查看进程间通信信息
(参数) -m 只查看共享内存的信息
-q 只查看消息队列的信息
-s 只查看信号量的信息
2. ipcrm: 用于删除进程间通信信息
(参数较多不一一介绍,只提一个常用的)
-m 删除共享内存的信息(需要知道要删除的信息的操作句柄)
eg:
ipcrm -m 0x12345678;
注意: 用ipcrm删除掉了信息,并不会立即删除,只不过是销毁了它的通信状态,直到共享内存的映射链接数变为 0 ,才会真正的删除。
具体操作代码:
编辑一个 shm_write.c 用来给共享内存写入数据
编辑一个 shm_read.c 用来读取共享内存中的数据
读取到的数据