• 专栏内容: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相关推荐

  1. Linux共享内存二维数组,linux系统编程--shmget shmat shmdt

    要使用共享内存,应该有如下步骤: 1.开辟一块共享内存 shmget() 2.允许本进程使用共某块共享内存 shmat() 3.写入/读出 4.禁止本进程使用这块共享内存 shmdt() 5.删除这块 ...

  2. linux的共享内存,linux共享内存实际在哪里?

    我只想知道共享内存驻留在Linux系统中的位置?它在物理内存还是虚拟内存中?linux共享内存实际在哪里? 我知道有关进程的虚拟内存发送信箱,他们从不同的工艺处理和流程没有看到对方的记忆,但我们可以利 ...

  3. Linux共享内存(二)

    Linux共享内存编程实例 原文链接:http://blog.csdn.net/pcliuguangtao/article/details/6526119 /*共享内存允许两个或多个进程进程共享同一块 ...

  4. 一文搞定:Linux 共享内存原理

    点击上方 "逆锋起笔" 关注,星标 干货第一时间送达 责编:Linux妹 | 来源:Linux云计算网络 在Linux系统中,每个进程都有独立的虚拟内存空间,也就是说不同的进程访问 ...

  5. c++ 共享内存_关于Linux共享内存的实验 [二] - 原因

    关于Linux共享内存的实验 [一] 上文采用的"删文件"和"杀进程"的方法主要是为了快速演示实验现象,但这种做法不利于通过调试手段进一步探究其内在的逻辑.为此 ...

  6. 共享内存---shmget shmat shmdt

    From: http://fengxue103.blog.hexun.com/32303320_d.html 要使用共享内存,应该有如下步骤: 1.开辟一块共享内存 shmget() 2.允许本进程使 ...

  7. 【Linux共享内存】

    Linux共享内存 一.基本概念 二.常用函数 1. shm_open 2. mmap 3. munmap 4. shm_unlink 5. ftruncate 三.使用示例 四.share内存不足解 ...

  8. 共享内存shmget的郁闷

    今天上午试验共享内存 shmget,但是总是不能成功申请到内存. 一开始还以为是第一个参数key有问题,调试了半天,发现key是正确的,没有报错,也可以根据不同路径变化. key_t ftok(con ...

  9. 共享内存 shmget函数

    内核共享内存 shmget 头文件 函数 #include <sys/ipc.h> #include <sys/shm.h>// 得到一个共享内存标识符或创建一个共享内存对象并 ...

最新文章

  1. rsync源目录写法的一点小细节
  2. 转]网络上收集的Visual Studio 2008的一些小技巧
  3. android中使用哪种方式解析XML比較好
  4. Dominant Character 思维,字符串,贪心
  5. 软件开发文档整理(之)一张示意图 | 清晰明了
  6. centeros7安装mysql - 风中追风_lonely - 博客园
  7. redis学习之三配置文件redis.conf 的含义
  8. 【渝粤题库】广东开放大学 商务办公软件应用与实践 形成性考核
  9. 多线程003 - 再谈CyclicBarrier
  10. 用JavaScript刷leetcode(刷题 第一天)
  11. oracle 中EXP、IMP 命令详解
  12. 21- vue django restful framework 打造生鲜超市 -首页商品分类显示功能
  13. 基本数据类型-集合(set)_上周内容回顾(字符串_数字_列表_元组_字典_集合)
  14. 良好的代码风格之if else?
  15. [bzoj1969] [Ahoi2005]LANE 航线规划
  16. python 核心编程 练习题
  17. CodeForces - 140C-New Year Snowmen
  18. 部落冲突-建筑大师基地军队建筑介绍(兵营、建筑大师训练营、星空实验室、战争机器)
  19. 向分布式存储系统的迁移-使用ZFS/Gluster
  20. 低通滤波器计算截止评率_科普文|一文了解电阻-电容(RC)低通滤波器

热门文章

  1. 单片机定时器和计数器的实验C语言,(单片机原理与应用)定时器/计数器设计实验...
  2. (javaweb-09) Filter
  3. 为什么iPhone通常比Android具有更好的音质?
  4. 机器学习中的特征选择——决策树模型预测泰坦尼克号乘客获救实例
  5. 花花野公子 - 野行之~昆明大理
  6. Hashcat使用指南
  7. Springboot 使用管道设计模式 , 实践案例玩一玩
  8. ET在课堂:S4A,新的重组方案
  9. python网络编程 赵宏_2018年Python爱好者社区历史文章合集(作者篇)
  10. vue下的@change事件