Linux中的共享内存
Linux中的共享内存
先简单写写这里,后面有时间慢慢深挖
共享内存是啥
这里摘抄一下维基百科:
共享内存(shared memory)指在多处理器的计算机系统中,可以被不同中央处理器访问的大容量内存。由于多个CPU需要快速访问存储器,这样就要对存储器进行缓存。由于其他处理器可能也要存取,任一缓存数据更新后,共享内存就需要立即更新,否则不同处理器可能用到不同的数据(参见缓存一致和内存一致)。
简单来说,共享内存(Shared Memory)就是允许多个进程访问同一个内存空间,是在多个进程之间共享和传递数据最高效的方式。
操作系统将不同进程之间共享内存安排为同一段物理内存,进程可以将共享内存连接到它们自己的地址空间中,如果某个进程修改了共享内存中的数据,其它的进程读到的数据也将会改变。
比较重要的一点:共享内存并未提供锁机制,也就是说,在某一个进程对共享内存的进行读写的时候,不会阻止其它的进程对它的读写(如果要对共享内存的读/写加锁,可以使用信号量)。
相关函数
头文件
在Linux中对于共享内存的操作首先要包含头文件:
|
|
创建或者获取共享内存——shmget函数
-
作用:创建一段共享内存或者读取已经存在的共享内存
-
函数原型:
1
int shmget(key_t key, size_t size, int shmflg);
-
参数:
key
:共享内存的键值,是一个整数,typedef unsigned int key_t
,是共享内存在系统中的编号,不同共享内存的编号不能相同,这一点由程序员保证,个人经验之谈,key
用十六进制表示比较好,因为一般在终端中查看时显示的也是十六进制,用十六进制设置比较直观也方便管理。size
:待创建的共享内存的大小,以字节为单位shmflg
:共享内存的访问权限,与文件的权限一样,0666|IPC_CREAT
表示全部用户对它可读写,如果共享内存不存在,就创建一个共享内存
-
返回值:
- 成功:将返回有效的共享内存标识符
- 失败或错误时,返回-1,并设置errno以指示错误。
连接共享内存——shmat函数
-
作用:把共享内存连接到当前进程的地址空间
-
函数原型:
1
void *shmat(int shm_id, const void *shm_addr, int shmflg);
-
参数:
shm_id
是由shmget
函数返回的共享内存标识- 参数
shm_addr
指定共享内存连接到当前进程中的地址位置,通常为空,表示让系统来选择共享内存的地址 - 参数
shm_flg
是一组标志位,通常为0。
-
返回值:
- 成功:返回一个指向共享内存第一个字节的指针
- 失败:返回(void*) -1,并设置errno以指示错误的原因
分离共享内存——shmdt函数
-
作用:将共享内存从当前进程中分离,相当于shmat函数的反操作
-
函数原型:
1
int shmdt(const void *shmaddr);
-
参数:
shmaddr
:是shmat函数返回的地址
-
返回值:
-
成功:返回0
-
失败:返回-1,并设置errno以指示错误的原因
-
删除共享内存——shmctl函数
-
作用:控制共享内存,这里注意一下,
shmctl
不仅可以删除共享内存,还可以做其他事情,但删除是这个函数最主要也是最常用的功能 -
函数原型:
1
int shmctl(int shm_id, int command, struct shmid_ds *buf);
-
参数(删除):
shm_id
是shmget
函数返回的共享内存标识符command
填IPC_RMID
buf
填0
-
返回值:
- 删除成功返回0(其他有部分操作不是,详情看man手册)
- 失败返回-1,并会设置对应errno
-
另外:用root创建的共享内存,不管创建的权限是什么,普通用户无法删除
其他命令操作
-
用
ipcs -m
可以查看系统的共享内存,内容有键值(key),共享内存编号(shmid),创建者(owner),权限(perms),大小(bytes)1 2 3 4 5 6 7 8 9
➜ c git:(main) ✗ ipcs -m ------------ 共享内存段 -------------- 键 shmid 拥有者 权限 字节 连接数 状态 0x00000000 4 sugar 600 524288 2 目标 0x00000000 7 sugar 600 524288 2 目标 0x00000000 11 sugar 600 4194304 2 目标 0x00000000 12 sugar 600 524288 2 目标 0x00005005 13 sugar 640 56 0
-
用
ipcrm -m
共享内存编号,可以手工删除共享内存1 2 3 4 5 6 7 8 9
➜ c git:(main) ✗ ipcrm -m 13 ➜ c git:(main) ✗ ipcs -m ------------ 共享内存段 -------------- 键 shmid 拥有者 权限 字节 连接数 状态 0x00000000 4 sugar 600 524288 2 目标 0x00000000 7 sugar 600 524288 2 目标 0x00000000 11 sugar 600 4194304 2 目标 0x00000000 12 sugar 600 524288 2 目标
补充一个小demo
程序A创建共享内存并写入
代码:
|
|
执行结果:
|
|
程序B读取共享内存并读出
代码:
|
|
执行结果:
|
|
|
|