共享内存之——system V共享内存
System V 的IPC对象有共享内存、消息队列、信号灯(量)。
注意:在IPC的通信模式下,不管是共享内存、消息队列还是信号灯,每个IPC的对象都有唯一的名字,称为"键(key)"。通过"键",进程能够识别所用的对象。"键"与IPC对象的关系就如同文件名称于文件,通过文件名,进程能够读写文件内的数据,甚至多个进程能够公用一个文件。而在IPC的通信模式下,通过"键"的使用也能使得一个IPC对象能为多个进程所共用。
一、System V共享内存机制:
system V IPC 机制下的共享内存本质是一段特殊的内存区域,进程间需要共享的数据被放在该共享内存区域中,所有需要访问该共享区域的进程都要把该共享区域映射到本进程的地址空间中去。共享内存允许一个或多个进程通过同时出现在他们的虚拟地址空间的内存进行通信,而这块虚拟内存的页面被每个共享进程的页表条目所引用,同时并不需要再所有进程的虚拟内存都有相同的地址。
1.System V共享内存是一种最为搞笑的进程间通信方式,进程可以直接读写内存,而不需要任何数据的拷贝。
2.为了在多个进程间交换信息,内核专门留出了一块内存区,可以由需要访问的进程将其映射到自己的私有地址空间。进程就可以直接读写这一块内存而不要进行数据的拷贝,从而大大提高效率。
3.由于多个进程共享一段内存,因此也需要依靠某种同步机制。
二、共享内存的操作流程
1. 创建/打开共享内存
2.映射共享内存,即把指定的共享内存映射到进程的地址空间用于访问
3.撤销共享内存的映射
4.删除共享内存对象
三、相关API
step.1----------------->获取一块共享内存
#include<sys/ipc.h>
#include<sys/shm.h> int shmget(key_t key, size_t size, int shmflg)
返回值:调用成功返回一个shmid(类似打开一个或创建一个文件获得的文件描述符一样);
调用失败返回-1;
参数说明:
(1)key:
这两种方式分配的共享内存,一般用来亲缘关系的进程间通信:
当key取值为IPC_PRIVATE,则函数shmget()将创建一块新的共享内存;
当key取值为0,而参数shmflg中设置了IPC_CREATE这个标志,则同样创建一块新的共享内存;
我们一般是通过ftok函数获取键值key
#include<sys/types.h>
#include<sys/ipc.h> key_t ftok(const char * pathname, int proj_id) /*pathname 就是指定的文件名(该文件必须是存在而且可以访问的)
id是标示符,和pathname一起完成创建键值的参数,虽然为int,但只有8个比特被使用,一般我们写一个字符代替*/
例如:
#include<sys/types.h>
#include<sys/ipc.h>
#include<stdio.h>
#include<stdlib.h> int main()
{
key_t key1,key2;
if((key1 = ftok(".",'a')) < )
{
perror("fail to ftok");
exit(EXIT_FAILURE);
}
if((key2 = ftok(".",'b')) < )
{
perror("fail to ftok");
exit(EXIT_FAILURE);
}
printf("key1 = %d\n",key1);
printf("key2 = %d\n",key2); return ;
}
(2)size:
是要建立共享内存的长度。所有的内存分配操作都是以页为单位的。所以如果一个进程只申请一块只有体格字节的内存,内存也会分配蒸蒸一页(在i386机器中一页的缺省大小PACE_SIZE = 4096B)
(3)shmflg:
指定创建或打开的标志和读写的权限(ipc_perm中的mode成员)。
有效的标志包括IPC_CREAT和IPC_EXCL,他们的功能与opene的O_CREAT和O_EXCL相当。
IPC_CREAT 如果共享内存不存在,则创建一个共享内存,否则直接打开已存在的。
IPC_EXCL 只有在共享内存不存在的时候,新的内存才建立,否则就产生错误。
/*假设键值为key,创建一个共享内存大小为4k,访问权限为0666
如果已经存在则返回其标示符*/
int shmid;
if((shmid = shmget(key, 4*1024, 0666 | IPC_CRREAT)) < 0)
{
perror("Fail to shmget");
exit(EXIT_FAILURE);
}
/*假设键值为key,创建一个共享内存大小为1k,访问权限为0666
如果已经存在则报错*/
int shmid;
if((shmid = shmget(key, , | IPC_CRREAT|IPC_EXCL)) < )
{
perror("Fail to shmget");
exit(EXIT_FAILURE);
}
step 2--------------------------->共享内存的映射
函数shmat将标示符为shmid共享内存映射到调用进程的地址空间中。
#include<sys/types.h>
#include<sys/shm.h> void * shmat(int shmid, const void *shmaddr, int shmflg);
参数说明:
shmid:要映射的共享内存区标示符
shmaddr:将共享内存映射到指定地址(若为NULL,则表示由系统自动完成映射)
shmflg:SHM_RDONLY 共享内存只读
默认0:共享内存可读写
返回值:调用成功返回映射后的地址,出错返回(void *)-1。
step3------------------------------>撤销共享内存与用户进程之间的映射
int shmdt(const void * shmadr);
参数shmaddr 是 shmat映射成功返回的地址。
注意:当一个进程不再需要共享内存段时,它将调用shmdt()系统调用取消这个段,但是这并不是从内核真正地删除这个段,而是把相关shmid_ds结构的shm_nattch域的值减1,当这个值为0时,内核才从物理上删除这个共享段。
step4-------------------------------->控制共享内存(&删除)
#inlcude<sys/ipc.h>
#include<sys/shm.h> int shmctl(int shmid, int cmd, struct shmid_ds *buf);
参数说明:
shmid 共享内存标示符ID
cmd IPC_STAT得到共享内存的状态
IPC_SET改变共享内存的状态
IPC_RMID删除共享内存
buf 是一个结构体指针。IPC_STAT的时候,取得的状态放在这个结构体中。如果要改变共享内存的状态,用这个结构体 struct shmid_ds 指定:
注意:
1.IPC_RMID命令实际上不从内核删除一个段,而是仅仅把这个段标记为删除,实际的删除发生最后一个进程离开这个共享段时。
2.当cmd为IPC_RMID时,第三个参数应为NULL。用这个函数“删除”共享内存
3.如果在代码中没有手动删除,共享内存并不会随着程序的终止而自动清理!
共享内存之——system V共享内存的更多相关文章
- Linux进程通信之System V共享内存
前面已经介绍过了POSIX共享内存区,System V共享内存区在概念上类似POSIX共享内存区,POSIX共享内存区的使用是调用shm_open创建共享内存区后调用mmap进行内存区的映射,而Sys ...
- 阐述linux IPC(五岁以下儿童):system V共享内存
[版权声明:尊重原创.转载请保留源:blog.csdn.net/shallnet 要么 .../gentleliu,文章学习交流,不用于商业用途] system V共享内存和posix ...
- UNIX环境高级编程——System V 共享内存区
共享内存区域是被多个进程共享的一部分物理内存.如果多个进程都把该内存区域映射到自己的虚拟地址空间,则这些进程就都可以直接访问该共享内存区域,从而可以通过该区域进行通信.共享内存是进程间共享数据的一种最 ...
- Linux IPC实践(9) --System V共享内存
共享内存API #include <sys/ipc.h> #include <sys/shm.h> int shmget(key_t key, size_t size, int ...
- php进程(线程)通信基础--System V共享内存
PHP默认情况没有开启功能,要支持该功能在编译PHP的时候要加入下面几个选项 System V消息,--enable-sysvmsg System V信号量支持,--enable-sysvsem ...
- System V 共享内存区
1.概述 系统调用mmap通过映射一个普通文件实现共享内存.System V 则是通过映射特殊文件系统shm中的文件实现进程间的共享内存通信.也就是说,每个共享内存区域对应特殊文件系统shm中的一个文 ...
- System V共享内存介绍
(一)简单概念 共享内存作为一种进程间通信的方式,其相较于其他进程间通信方式而言最大的优点就是数据传输速率快.其内部实现的方式采用了Linux进程地址空间中的mmap文件映射区,将文件内容直接映射到各 ...
- Linux system v 共享内存
system v 共享内存 #include <sys/types.h> #include <sys/shm.h> int shmget(key_t key, size_t s ...
- System V共享内存
目录 1. 概述 2. System V共享内存API shmget shmat shmdt shmctl 3. 简单的程序 代码实现 common.h shmcreate.c shmrmid.c s ...
随机推荐
- sqlite3 数据库使用
首先,通过官网下载sqlite3.h和sqlite3.c两个文件,用于调用里面的api函数操作数据库. 这里也提供链接地址下载:http://pan.baidu.com/s/1qWzjqPY 其中里面 ...
- 如何用纯 CSS 创作一个行驶中的火车 loader
效果预览 在线演示 按下右侧的"点击预览"按钮可以在当前页面预览,点击链接可以全屏预览. https://codepen.io/comehope/pen/RBLWzJ 可交互视频 ...
- 常用排序算法的总结以及编码(Java实现)
常用排序算法的总结以及编码(Java实现) 本篇主要是总结了常用算法的思路以及相应的编码实现,供复习的时候使用.如果需要深入进行学习,可以使用以下两个网站: GeeksForGeeks网站用于学习相应 ...
- XenServer 6.5 安装
为了方便截图我下面的所有操作都是在VMware Workstation 11 上面完成的,但在之后的所有Citrix产品的操作中都将会在物理环境完成,物理机安装XS的步骤和下面是相同的. 1.打开Wo ...
- 【Alpha】Scrum Meeting 5-end
第一天:2019/6/19 前言: 第5次会议在6月19日由PM在教9C-501召开. 总结项目,进行单元测试并进行简单的整合.时长60min. 团队GitHub仓库 仓库连接 1.1 今日完成任务情 ...
- python-安装及配置环境变量
1.python安装十分简单,直接下载与自己电脑位数匹配的python安装包进行安装即可. 这里提供python27的安装包供大家参考. win-32位: 链接: https://pan.baidu. ...
- 大数据学习——spark学习
计算圆周率 [root@mini1 bin]# ./run-example SparkPi [root@mini1 bin]# ./run-example SparkPi [root@mini1 bi ...
- python_字符串,元组,格式化输出
一.字符串 1.字符串是有成对的单引号或者双引号括起来的.例如:name="张三",sex="女" 2.字符串的索引是从0开始的 3.字符串的切片 a.单个字符 ...
- 微信小程序开发 -- 设置屏幕亮度
wx.setScreenBrightness(OBJECT) 设置屏幕亮度. OBJECT参数说明: 参数 类型 必填 说明 value Number 是 屏幕亮度值,范围 0~1,0 最暗,1 最亮 ...
- Cookie和Session的作用和工作原理
一.Cookie详解 (1)简介 因为HTTP协议是无状态的,即服务器不知道用户上一次做了什么,这严重阻碍了交互式Web应用程序的实现.在典型的网上购物场景中,用户浏览了几个页面,买了一盒饼干和两饮料 ...