Linux:共享内存
共享内存的原理在物理内存中开辟一块空间;不同进程通过页表将该空间映射到字节的进程虚拟地址空间中;不同进程通过操作自己进程虚拟地址空间当中的虚拟地址,来操作共享内存;使用共享内存步骤:创建共享内存;附加,将进程附加该共享内存上(将进程虚拟地址和物理地址通过页表建设映射关系);分离,将虚拟地址和物理地址的映射关系从页表中删除共享内存映射到物理地址空间时 ,是映射在共享区中(在栈区和堆区中间)共享内存接
共享内存是系统级别的接口
进程间通信的本质是,让不同的进程看到同一份资源
共享内存的处理不同于管道
system V下的共享内存生命周期是跟随内存的,如果不显示删除就需要os重启解决
ipcs -m查看当前用户创建的共享内存
ipcem -m shmid删除对应的共享内存
key是共享内存的内核标识符,shmid是用户层面的标识符
共享内存也是有权限的,0就是都不能访问
1.共享内存的原理
共享库会映射到堆栈中间的区域:
把磁盘中的数据加载到内存中,操作系统建立映射,经过页表映射到地址空间中的共享区中,需要库就跳转过去执行。不止是库可以映射
- 两个进程有各自的页表,映射到物理内存的不同区域,所以有了独立性
- 现有一个特定的接口,能在物理内存中创建好空间
- 把这个共享空间,通过这个两个进程调用该接口映射到各自的地址空间中
- 把这个空间的起始地址返回给用户,用户就能找到这个空间了
2.使用共享内存步骤:
- 创建共享内存;
- 附加,将进程附加该共享内存上(将进程虚拟地址和物理地址通过页表建设映射关系);
- 分离,将虚拟地址和物理地址的映射关系从页表中删除
共享内存映射到物理地址空间时 ,是映射在共享区中(在栈区和堆区中间)
在使用共享内存时,进程就把他当作自己的空间使用就行
3.共享内存接口:
创建共享内存就是os在物理内存中开辟一段空间
os看待物理内存是将其(一页4kb,4G内存有2^20个页)看成这么多页
os需要管理这些页,通过数组管理,这个数组类型就是共享内存的各个属性
进程通信时,共享内存需要其中一个进程创建,flag就是处理进程面对有无共享内存的情况
创建或者获取共享内存shmget
- key值由用户提供,是共享内存的唯一值
原因:
如果是os提供,另一个进程怎么知道共享内存呢,为了让两个进程看到同一个共享内存,所以让两个进程拥有同一个key值就行- 如何保证key的值唯一
这个函数找到特定的文件,结合自己设定的值(0-255),会将文件的inode和项目id做组合形成一过唯一值返回给key
creat含义是获取内存,不存在就创建
execl含义如果不存在指定的共享内存,则创建,存在就出错返回;可以保证get函数调用成功是一过全新的内存
- 搭配使用是要获得自己创建的共享内存,不使用别人的
- 共享内存创建时也需要设置权限信息,需要按位或上共享内存的权限(八进制数字)表示
大小最好设置成页的整数倍(4kb)
共享内存大小最好设置成页的整数倍,os和磁盘io时基本单位是4kb,
内存在哪:内核中维护共享内存的结构
附加接口:将共享内存附加到当前内存上
附加上后,就是进程多了一份内存空间
分离:
将共享内存从进程中分离出来,分离时需告诉shmdt函数刚附加共享内存到进程后,进程虚拟地址的位置
控制共享内存:
获取属性,设置属性,删除共享内存
4.共享内存的命令
ipcs:输出消息队列,共享内存,信号量信息
ipcs -m:只输出共享内存信息
key | 共享内存标识符 |
---|---|
shimd | 共享内存操作句柄 |
owner | 内存创建者 |
perms | 内存权限 |
bytes | 内存大小 |
nattch | 附加进程数量 |
statu | 没有显式表示该共享内存正常 |
ipcrm -m +shmid 将共享内存从物理内存中删除
- 内核中有一个结构体维护着在物理空间的共享内存
- 删除0附加进程的共享内存,则内核当中的结构体和物理空间也被删除
- 删除有附加进程的共享内存,则将该共享内存的key(标识符)变成0x 0000 0000;
表示当前共享内存不能被其它进程附加,共享内存的状态被置就被置为dest;
该现象是因为内核中描述共享内存的结构体没有被删除(如下图所示);
删除后产生了两种结果的原因:
- 共享内存的物理空间没有被其它内存使用,则能正常运行;
- 如果该空间被别的进程使用就会崩溃;
描述共享内存的结构体内部的引用计数一旦为0(mywrite进程停止),则共享内存结构体被释放
共享内存的特性:
共享内存是写的时候是覆盖写,读的时候是拷贝(也就是数据访问)
- 将字符串写入共享内存后,写操作进程结束,在多次读取依旧能多次读取成功;
- 所以共享内存的生命周期跟随操作系统内核,不主动删除则一直存在;
基于共享内存+管道的访问控制
进程退出,共享内存依然是存在的,生命周期是随内存的
shmid是提供给用户的,ipcrm -m删除时就删shmid
申请4097个大小的共享内存,OS会申请8kb大小,但是只能使用4097个字节
因为共享内存无法做到访问控制,读端会一直读取数据
更多推荐
所有评论(0)