linux 共享内存 shmget
- 专栏内容:linux下并发编程
- 个人主页:我的主页
- 座右铭:天行健,君子以自强不息;地势坤,君子以厚德载物.
目录
前言
概述
原理机制
系统命令
接口说明
代码演示
结尾
前言
本专栏主要分享linux下并发编程相关知识,包括多进程,多线程,进程/线程间通信,并发同步控制,以及高并发下性能提升,请大家多多留言。
概述
共享内存是进程间通信的一种常用手段,相较于其它通信方法,它可以在进程间传递大量的不同格式的数据,同时这些数据不需要持久保存在磁盘上。
原理机制
共享内存相当于操作系统在进程的地址空间外,再开辟了一段物理内存,再把这段物理内存映射到进程的虚拟地址空间内,这样进程就可以访问了。
那么不同进程如何知道这段物理内存呢?
所以,第一步是确定一个唯一的key值,把这个key在不同进程间传递,不同进程拿到后就可以用这个key值向操作系统查到共享内存空间。
第二步,就是映射到进程的内存空间。我们都知道,进程的内存空间是一个虚拟地址空间,通过段页机制将物理内存地址转成虚拟内存地址,所以此处的共享内存,也需要把它挂到进程的虚拟地址空间中,进程才可以访问,不然还是找不到。
第三步,此时就可以直接读写了。
第四步,使用完成后,资源需要释放,否则会造成内存泄漏,这可是编程的大忌。因为涉及到多个进程共同使用,当然我们释放有两种形式,一是当前进程不再引用使用,此时共享内存还存在;一种是其它进程不再使用时,删除共享内存,此时共享内存就彻底不存在了。
系统命令
查询共享内存系统资源,使用系统命令
ipcs -m
查询结果如下:
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
0x0101de21 229412 test 600 8192 1
手动使用系统命令删除共享内存,使用共享内存的id
ipcrm -m shmid
接口说明
接口对应的头文件为
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
(1)创建和获取已有的共享内存,每个共享内存都有唯一的key来标识,key值可以用IPC_PRIVATE,也可以用ftok函数生成。
int shmget(key_t key, size_t size,int shmflg);
size ,共享内存的大小,分配时会与PAGE_SIZE向上取整;
shmflg,可以取值
IPC_CREAT |
创建共享内存,如果不带时,只是查找key值标识的共享内存 |
IPC_EXCL |
与IPC_CREATE一起使用,如果已经有key标识的共享内存时,就会失败 |
SHM_HUGETLB |
创建大页内存,一般页面大小为2KB/4KB,这里可以使更大的页面,在密集型读时可以得到性能提升; |
SHM_HUGE_2MB |
同上,创建2MB的大页内存 |
SHM_NORESERVE |
不为此共享内存使用swap空间 |
(2)映射到进程私有虚拟地址空间
void * shmat(int shmid, char __user * shmaddr, int shmflg);
将shmid标识的共享内存,映射到shmaddr对应的进程内存地址上,映射后的地址是与SHMLBA向下对齐的地址。如果地址为空,则由系统选择一块进程空闲空间进行映射。
关于SHMLBA,这是关于CPU cache调度相关,有些话长,在另外一篇博文中专门解释。
shmflg,标识共享内存的使用权限,可以取值
SHM_EXEC |
共享内存可以有执行权限 |
SHM_RDONLY |
以只读权限使用共享内存 |
SHM_REMAP |
如果当前映射地址已经有映射有其它共享内存,可以进行替换 |
(3)解除与当前进程的映射
int shmdt(const void *shmaddr);
当然这里只是与当前进程解除了映射,内核资源也仅仅对引用计数减一,并没有删除;
(4)删除共享内存资源
int shmctl(int shmid, int cmd, struct shmid_ds * buf);
此系统函数,可以对共享内存进行一些控制操作,其中包括删除共享资源,由cmd来指定对应的操作;
cmd,可以取下面的值
IPC_STAT |
调用者需要有读权限,会将kernal中共享内存信息拷到buf中返回 |
IPC_SET |
可以设置shmid_ds结构成员的信息 |
IPC_RMID |
销毁共享内存,当然必须是引用计数为0,调用者一定是创建者或最后一个使用进程 |
IPC_INFO |
获取共享内存的系统限制相关参数值 |
SHM_INFO |
获取共享内存资源使用情况 |
SHM_STAT |
同IPC_STAT |
SHM_LOCK |
锁定共享内存,此时内存页面不会被替换 |
SHM_UNLOCK |
解除锁定 |
(5)ftok系统函数对应的头文件与声明如下:
#include <sys/types.h>
#include <sys/ipc.h>
key_t ftok(const char *pathname, int proj_id);
代码演示
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>#define SHM_SIZE 8192
int main(int argc ,char *argv[])
{key_t shm_key = ftok(".", 1);int shm_id = -1;char *pshm = NULL;char str[] = "Hello, World!";int pid = 0;int underSubprocess = 0;shm_id = shmget(shm_key, SHM_SIZE, 0600|IPC_CREAT);if(shm_id < 0){printf("get shm error [%s]\n",strerror(errno));return -1;}pshm = (char *)shmat(shm_id, NULL, 0);if(pshm == (char *)-1){printf("attach sharememory error [%s]\n", strerror(errno));return -1;}pid = fork();if(pid == 0){// under subprocessprintf("I'm in the subprocess\n");sleep(2);printf("recv: %s\n",pshm);underSubprocess = 1;}else if(pid > 0){strncpy(pshm, str, sizeof(str));sleep(5);printf("I'm father ,will exit.\n");}else{printf("fork error\n");}if(-1 == shmdt(pshm)){printf("detach sharememory error [%s]\n",strerror(errno));return -1;}if(underSubprocess == 0)shmctl(shm_id, IPC_RMID, NULL);return 0;
}
在运行过程中查看系统共享内存
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
0x0101de21 229412 test 600 8192 1
确实已经创建了。
结尾
作者邮箱:study@senllang.onaliyun.com
如有错误或者疏漏欢迎指出,互相学习。另外有什么想要了解的内容,也可以给我发邮件,互相谈讨,定知无不言。
注:未经同意,不得转载!
linux 共享内存 shmget相关推荐
- Linux共享内存二维数组,linux系统编程--shmget shmat shmdt
要使用共享内存,应该有如下步骤: 1.开辟一块共享内存 shmget() 2.允许本进程使用共某块共享内存 shmat() 3.写入/读出 4.禁止本进程使用这块共享内存 shmdt() 5.删除这块 ...
- linux的共享内存,linux共享内存实际在哪里?
我只想知道共享内存驻留在Linux系统中的位置?它在物理内存还是虚拟内存中?linux共享内存实际在哪里? 我知道有关进程的虚拟内存发送信箱,他们从不同的工艺处理和流程没有看到对方的记忆,但我们可以利 ...
- Linux共享内存(二)
Linux共享内存编程实例 原文链接:http://blog.csdn.net/pcliuguangtao/article/details/6526119 /*共享内存允许两个或多个进程进程共享同一块 ...
- 一文搞定:Linux 共享内存原理
点击上方 "逆锋起笔" 关注,星标 干货第一时间送达 责编:Linux妹 | 来源:Linux云计算网络 在Linux系统中,每个进程都有独立的虚拟内存空间,也就是说不同的进程访问 ...
- c++ 共享内存_关于Linux共享内存的实验 [二] - 原因
关于Linux共享内存的实验 [一] 上文采用的"删文件"和"杀进程"的方法主要是为了快速演示实验现象,但这种做法不利于通过调试手段进一步探究其内在的逻辑.为此 ...
- 共享内存---shmget shmat shmdt
From: http://fengxue103.blog.hexun.com/32303320_d.html 要使用共享内存,应该有如下步骤: 1.开辟一块共享内存 shmget() 2.允许本进程使 ...
- 【Linux共享内存】
Linux共享内存 一.基本概念 二.常用函数 1. shm_open 2. mmap 3. munmap 4. shm_unlink 5. ftruncate 三.使用示例 四.share内存不足解 ...
- 共享内存shmget的郁闷
今天上午试验共享内存 shmget,但是总是不能成功申请到内存. 一开始还以为是第一个参数key有问题,调试了半天,发现key是正确的,没有报错,也可以根据不同路径变化. key_t ftok(con ...
- 共享内存 shmget函数
内核共享内存 shmget 头文件 函数 #include <sys/ipc.h> #include <sys/shm.h>// 得到一个共享内存标识符或创建一个共享内存对象并 ...
最新文章
- rsync源目录写法的一点小细节
- 转]网络上收集的Visual Studio 2008的一些小技巧
- android中使用哪种方式解析XML比較好
- Dominant Character 思维,字符串,贪心
- 软件开发文档整理(之)一张示意图 | 清晰明了
- centeros7安装mysql - 风中追风_lonely - 博客园
- redis学习之三配置文件redis.conf 的含义
- 【渝粤题库】广东开放大学 商务办公软件应用与实践 形成性考核
- 多线程003 - 再谈CyclicBarrier
- 用JavaScript刷leetcode(刷题 第一天)
- oracle 中EXP、IMP 命令详解
- 21- vue django restful framework 打造生鲜超市 -首页商品分类显示功能
- 基本数据类型-集合(set)_上周内容回顾(字符串_数字_列表_元组_字典_集合)
- 良好的代码风格之if else?
- [bzoj1969] [Ahoi2005]LANE 航线规划
- python 核心编程 练习题
- CodeForces - 140C-New Year Snowmen
- 部落冲突-建筑大师基地军队建筑介绍(兵营、建筑大师训练营、星空实验室、战争机器)
- 向分布式存储系统的迁移-使用ZFS/Gluster
- 低通滤波器计算截止评率_科普文|一文了解电阻-电容(RC)低通滤波器
热门文章
- 单片机定时器和计数器的实验C语言,(单片机原理与应用)定时器/计数器设计实验...
- (javaweb-09) Filter
- 为什么iPhone通常比Android具有更好的音质?
- 机器学习中的特征选择——决策树模型预测泰坦尼克号乘客获救实例
- 花花野公子 - 野行之~昆明大理
- Hashcat使用指南
- Springboot 使用管道设计模式 , 实践案例玩一玩
- ET在课堂:S4A,新的重组方案
- python网络编程 赵宏_2018年Python爱好者社区历史文章合集(作者篇)
- vue下的@change事件