文章目录
1. 共享内存原理及图解
共享内存通过页表映射到进程的进程虚拟地址空间的共享区中,进程通过操控共享区的内容,间接操作共享内存中的内容
不同的进程将同一块共享内存映射到自己的共享区中,通过操作各自的共享区,以达到进程间数据交换
2. 共享内存相关函数及命令
2.1 创建共享内存函数
shmget函数
int shmget(key_t key, size_t size, int shmflg);
功能:开辟一段共享内存,用共享内存标识符key去标识这块内存,并返回共享内存的操作句柄
头文件:
- sys/ipc.h
- sys/shm.h
参数:
- key : 共享内存标识符,相当于共享内存的身份证,唯一标识共享内存区域
- size : 需要开辟的共享内存大小,单位是字节
- shmflg
宏 | 含义 |
---|---|
IPC_CREAT | 若共享内存不存在,则创建 |
IPC_EXCL | 与IPC_CREAT一同使用,为了确保共享内存已经存在时,会报告错误 |
返回值:创建成功返回 共享内存操作句柄 ,创建失败返回 -1
共享内存标识符:用于唯一标识某块共享内存的,进程可以通过共享内存标识符找到这块共享内存
共享内存操作句柄:用于操作这块内存的
代码演示shmget函数
#include <stdio.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#define KEY 0x89898989
int main()
{
int shmid = shmget(KEY,1024,IPC_CREAT);
if(shmid < 0)
{
perror("shmget");
return -1;
}
printf("shmid : %d\n",shmid);
return 0;
}
[gongruiyang@localhost Testshm]$ ./shm
shmid : 425985
2.2 查看共享内存命令
ipcs命令用于查看所有进程间通信(IPC)信息,-m选项是所有信息中过滤出共享内存段的进程间通信信息
ipcs -m
命令演示
[gongruiyang@localhost Testshm]$ ipcs -m
------------ 共享内存段 --------------
key shmid owner 权限 字节 nattch status
0x00000000 262144 gongruiyan 600 524288 2 dest
0x89898989 425985 gongruiyan 0 1024 0 dest
0x00000000 393218 gongruiyan 600 524288 2 dest
- key : 共享内存标识符,若为
- shmid : 共享内存操作句柄
- owner : 所属用户,谁创建的
- 权限 : 对该共享内存的操作权限
- 字节 : 共享内存大小
- nattch : 附加的进程数量
- status : 共享内存段的状态,dest表示销毁
上面的程序创建了一个进程标识符为0x89898989的共享内存段,虽然程序已经执行结束,但是共享内存段仍然存在,说明共享内存的生命周期的结束不是跟随程序的,而是跟随内核的
2.3 删除共享内存命令
ipcrm用于删除进程间通信资源,-m代表删除的是共享内存段
ipcrm -m 共享内存操作句柄
命令演示
[gongruiyang@localhost Testshm]$ ipcs -m
------------ 共享内存段 --------------
key shmid owner 权限 字节 nattch status
0x00000000 262144 gongruiyan 600 524288 2 dest
0x89898989 425985 gongruiyan 0 1024 0 dest
0x00000000 393218 gongruiyan 600 524288 2 dest
[gongruiyang@localhost TestPipeCS]$ ipcrm -m 425985
[gongruiyang@localhost TestPipeCS]$ ipcs -m
------------ 共享内存段 --------------
键 shmid 拥有者 权限 字节 nattch 状态
0x00000000 262144 gongruiyan 600 524288 2 dest
0x00000000 393218 gongruiyan 600 524288 2 dest
2.4 创建共享内存时赋予读写权限
由上面程序创建出来的共享内存的权限为0可以看出,我们对该共享内存无任何权限,我们可以在创建共享内存的时候对共享内存属性进行修改,增加 权限
int shmid = shmget(KEY,1024,IPC_CREAT | 0664);
2.5 将自定义的共享内存映射到进程虚拟地址的共享区中
void *shmat(int shmid, const void *shmaddr, int shmflg);
功能:将指定的共享内存段映射到进程虚拟地址的共享区中的某一块中
头文件:
- sys/types.h
- sys/shm.h
参数:
- shmid : 共享内存操作句柄
- shmaddr : 映射到共享区的哪一块地址,需要映射到哪一块地址就填哪块地址;如果填入NULL就代表想让操作系统替我们选择一个合适的地址,
- shmflg :
宏 | 含义 |
---|---|
SHM_RDONLY | 规定当前进程对该共享内存有 只读权限 |
0 | 规定当前进程对该共享内存有 读写权限 |
返回值:返回 映射到的共享区 的地址
程序演示
#include <stdio.h>
#include <unistd.