操作系统之共享存储区详解(Linux shm)
在学习操作系统的时候,老师讲到进程间通信,今天在这里介绍一下进程通信中的共享存储区通信
一、基本介绍
共享内存分为两种,以下是维基百科上的说法:
硬件术语
共享内存指在多处理器的计算机系统中,可以被不同中央处理器访问的大容量内存。由于多个CPU需要快速访问存储器,这样就要对存储器进行缓存。由于其他处理器可能也要存取,任一缓存数据更新后,共享内存就需要立即更新,否则不同处理器可能用到不同的数据(参见缓存一致和内存一致)。
共享内存的类似方案有分布内存、分布共享内存,用以解决同类问题。
软件术语
在软件中,术语共享内存指可被多个进程存取的内存,一个进程是一段程序的单个运行实例。在这种情况下,共享内存被用作进程间的通讯。
我今天在这里介绍shm共享内存。使用共享内存进行进程通信时需要用到四个函数:shmget(),shmat(),shmdt(),shmctl()。这四个函数的使用需要声明sys/shm.h头文件
#include<sys/shm.h>
二、函数解释
①shmget()
get
函数原型:
int shmget(key_t key,size_t size,int shmflg);
shmget()用来获得共享内存区域的ID(如果不存在该共享内存区域则创建一个新的共享内存区域)
参数解释
key_t key 共享内存标识符,两个不相关的进程之间我们可以自定义一个key来使用,若为父子进程的话,该标识符可为IPC_PRIVATE(需要在父子进程都可见的地方调用(即在创建子进程之前),否则不能实现内存的共享)。
size_t size 共享内存size。
int shmflag 权限标志,内存模式(mode)
引用自
https://blog.csdn.net/qustdjx/article/details/7708311
shmflg主要和一些标志有关。其中有效的包括IPC_CREAT和IPC_EXCL,它们的功能与open()的O_CREAT和O_EXCL相当。
IPC_CREAT 如果共享内存不存在,则创建一个共享内存,否则打开操作。
IPC_EXCL 只有在共享内存不存在的时候,新的共享内存才建立,否则就产生错误。
如果单独使用IPC_CREAT,shmget()函数要么返回一个已经存在的共享内存的操作符,要么返回一个新建的共享内存的标识符。
如果将IPC_CREAT和IPC_EXCL标志一起使用,shmget()将返回一个新建的共享内存的标识符;如果该共享内存已存在,或者返回-1。
IPC_EXEL标志本身并没有太大的意义,但是和IPC_CREAT标志一起使用可以用来保证所得的对象是新建的,而不是打开已有的对象。
这个可以用,但最好不要用:
对于用户的读取和写入许可指定SHM_R和SHM_W;
(SHM_R>3)和(SHM_W>3)是一组读取和写入许可,而(SHM_R>6)和(SHM_W>6)是全局读取和写入许可。
推荐使用这个:
可以使用0666|IPC_CREAT,来作为shmflg的值。
返回值
成功返回共享内存的标识符;不成功返回-1,errno储存错误原因。
EINVAL 参数size小于SHMMIN或大于SHMMAX。
EEXIST 预建立key所致的共享内存,但已经存在。
EIDRM 参数key所致的共享内存已经删除。
ENOSPC 超过了系统允许建立的共享内存的最大值(SHMALL )。
ENOENT 参数key所指的共享内存不存在,参数shmflg也未设IPC_CREAT位。
EACCES 没有权限。
ENOMEM 核心内存不足。
②shmat()
attach
函数原型:
void *shmat(int shm_id,const void *shm_addr int shmflg);
shmat()用来启动对这个共享内存区域的访问,连接到用户的虚地址空间。
参数解释
int shm_id 共享进程区域的ID
void *shm_addr
int shmflg 内存的操作模式。如果是SHM_RDONLY的话,就是只读模式。其它的是读写模式。成功时,这个函数返回共享内存的起始地址。失败时返回-1。
③shmdt()
detach
函数原型:
int shmdt(const void *shm_addr);
shmdt()用来删除本进程对这块内存的使用,shmdt()与shmat()相反,是用来禁止本进程访问一块共享内存的函数。
参数解释
void *shm_addr 共享内存区域的起始地址
成功返回0
失败返回-1
④shmctl()
control
函数原型:
int shmctl(int shm_id,int command,struct shmid_ds *buf);
shmctl() 控制对此共享内存的使用
参数解释
int shm_id 共享内存区域的ID
int command(cmd) 控制命令
IPC_STAT//获得共享内存的状态
IPC_SET//改变共享内存的状态
IPC_RMID//删除共享内存
struct shmid_ds *buf 为一个结构体指针,指向共享内存mode和访问权限的结构。
struct shmid_ds {struct ipc_perm shm_perm; /* Ownership and permissions */size_t shm_segsz; /* Size of segment (bytes) */time_t shm_atime; /* Last attach time */time_t shm_dtime; /* Last detach time */time_t shm_ctime; /* Last change time */pid_t shm_cpid; /* PID of creator */pid_t shm_lpid; /* PID of last shmat(2)/shmdt(2) */shmatt_t shm_nattch; /* No. of current attaches */...
};
上代码:
#include<bits/stdc++.h>
#include<unistd.h>
#include<sys/time.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<sys/ipc.h>
#include<sys/shm.h>
using namespace std;
#define SHMkey 75
int shmid,p1,p2;
int *addr;
void client()
{shmid=shmget(SHMkey,1024,0777);addr=((int*)shmat(shmid,0,0));for(int i=9;i>=1;i--){while(*addr!=-1);cout<<"(client)message sent"<<endl;*addr=i;cout<<*addr<<endl;sleep(2);}
}
void server()
{shmid=shmget(SHMkey,1024,0777 | IPC_CREAT);addr=((int*)shmat(shmid,0,0));//addr=shmat(shmid,0,0);//连接到用户的虚地址空间do{*addr =-1;while(*addr==-1);//client是否已经读取cout<<"(server)message received"<<*addr<<endl;sleep(2);}while(*addr);shmctl(shmid,IPC_RMID,0);
}
int main()
{p1=fork();if(p1==0){server();}else{p2=fork();if(p2==0){client();}}wait(0);wait(0);return 0;
}
上列代码中,在调用shmat()时,需要用到强制类型转换,因为shmat的函数原型是void*类型,而我们需要得到int型的返回值,需要加上((int *)shmat(shmid,0,0));
操作系统之共享存储区详解(Linux shm)相关推荐
- linux日志配置含义,Linux操作系统中的日志功能详解
日志系统将我们系统运行的每一个状况信息都使用文字记录下来,这些信息有助我们观察系统运行过程中正常状态和系统运行错误时快速定位错误位置的途径等;下面学习啦小编主要概述一下Linux操作系统中的日志功能. ...
- linux系统电脑的权限设置,Linux下的文件权限设置修改详解linux操作系统 -电脑资料...
在linux中更改所属用户组是使用chgrp,更改文件拥有者, chown,更改9个属性, chmod这三种常用的问题,在linxu中这三个命令就是对文件目录权限的控制命令了,下面我来介绍它们的用法与 ...
- linux mv复制命令,linux中删除复制移动文件rm,mv,cp命令详解linux操作系统 -电脑资料...
在linux中对文件的复制删除移动分别会使用到rm,mv,cp三个命令,下面我来给大家介绍一下rm,mv,cp命令对文件的常规操作吧, 先看实例 删除复制移动文件命令 Linux代码 rm -rf / ...
- 11月26日:操作系统实验杂记 shmget(创建共享存储区) shmat(连接共享存储区) shmdt(断连共享存储区) shmctl(共享存储区控制)
文章目录 函数语法介绍 1.创建共享存储区shmget 2.连接共享存储区shmat 3.断连共享存储区shmdt 4.控制共享存储区shmctl 示例程序代码 进程1代码 进程2代码 函数语法介绍 ...
- linux权限644是什么,linux系统644、755、777权限详解linux操作系统 电脑资料
linux系统644.755.777权限详解linux操作系统 电脑资料 在linux系统中644.755.777三种权限是非常重要的一些权限了,下面我来详细的介绍644.755.777三种权限的使用 ...
- linux 内存 参数,linux free命令参数及用法详解(linux查看内存命令)
linux free命令参数及用法详解(linux查看内存命令) 2019年05月31日 | 萬仟网科技 | 我要评论 free指令会显示内存的使用情况,包括实体内存,虚拟的交换文件内存,共享内存区段 ...
- HTML5本地存储使用详解
HTML5本地存储使用详解 前言 随着Web应用的发展,需要在用户本地浏览器上存储更多的应用数据,传统的cookie存储的方案已经不能满足发展的需求,而使用服务器端存储的方案则是一种无奈的选择.HTM ...
- 详解Linux运维工程师打怪升级篇
详解 Linux 运维工程师打怪升级篇 积累经验篇 做运维也快4年多了,就像游戏打怪升级,升级后知识体系和运维体系也相对变化挺大,学习了很多新的知识点. 运维工程师 是从一个呆逼进化为苦逼再成长为牛逼 ...
- Mysql存储引擎详解(MyISAM与InnoDB的区别)
Mysql存储引擎详解(MyISAM与InnoDB的区别) 存储引擎 MySQL中的数据用各种不同的技术存储在文件(或者内存)中.这些技术中的每一种技术都使用不同的存储机制.索引技巧.锁定水平 ...
最新文章
- 如何用计算机对cad的草图,AutoCAD2020图纸如何导入su草图大师软件?
- Bootstrap3.0学习第十轮(下拉菜单、按钮组、按钮式下拉菜单)
- python中的迭代器,生成器,闭包,装饰器,@property
- 快速上手SpyGlass——CDC检查
- JVM垃圾收集器与内存分配策略学习总结
- PHP双码率视频云转码服务系统源码 m3u8切片秒切html5播放器 全开源
- select语句一些要点(一)
- leetcode组队学习——查找(一)
- 图像仿射变换 图像平移 python实现
- Linux嵌入式开发_主设备号与次设备号详解
- [OpenCV+VS2015]火焰检测算法(RGB判据)
- 罗克露计算机组成,罗克露计算机组成原理课件(一)
- Office 2010安装过程中修复“错误2203。发生内部错误”
- 梁念坚致辞Tech ED2009 主推Windows7
- 对vue初学者建议 vue如何上手
- 计算机和人脑在线阅读,人脑与电脑(原文)
- 计算机中rom,计算机中rom指的是内存还是外存
- iphone通讯录 android,3个方法,教你如何快速而又有效的将联系人从iPhone转移到安卓...
- 要关闭python解释器可使用函数或者快捷键_超星尔雅中华传统文化之戏曲瑰宝第七章节测验网课答案选修课慕课答案...
- PTA 7-172 元宵花灯
热门文章
- 15. python数据类型转换
- matlab半张量积,半张量积原理.doc
- 吉大20春学期计算机系统结构在线作业一,吉大20春学期《internet应用技术》在线作业一-2(答案)...
- hdu4422The Little Girl who Picks Mushrooms
- 使用高德地图api去掉地图左下角的logo
- 文件移动renameTo()与move()
- 一个随时随地写Python代码的神器 Pythonista
- 使用JS中EL数组中循环取值
- 山寨风,高仿QQ附近的人筛选功能的滑动选择列表来袭!
- 计算机信息系统集成资质是否取消?