一、共享内存相关知识

所谓共享内存,就是多个进程间共同地使用同一段物理内存空间,它是通过将同一段物理内存映射到不同进程的 虚拟空间来实现的。由于映射到不同进程的虚拟空间中,不同进程可以直接使用,不需要像消息队列那样进行复制,所以共享内存的效率很高。共享内存可以通过mmap()映射普通文件机制来实现,也可以System V共享内存机制来实现,System V是通过映射特殊文件系统shm中的文件实现进程间的共享内存通信,也就是说每个共享内存区域对应特殊文件系统shm中的一个文件。

二、共享内存原理

System V共享内存把所有共享数据放在共享内存区,任何想要访问该数据的进程都必须在本进程的地址空间新增一块内存区域,用来映射存放共享数据的物理内存页面。System V共享内存通过shmget函数获得或创建一个IPC共享内存区域,并返回相应的标识符,内核在保证shmget获得或创建一个共享内存区,初始化该共享内存区相应的shmid_kernel结构,同时还将在特殊文件系统shm中创建并打开一个同名文件,并在内存中建立起该文件的相应的dentry及inode结构,新打开的文件不属于任何一个进程,所有这一切都是系统调用shmget函数完成的。

三、sysctl.conf 配置文件

以上两段说明部分是从互联网中找到的理解的内容。而做为Linux系统维护人员,能接触到的与共享内存相关的设置主要在/etc/sysctl.conf中的几个配置项。具体如下:

  1. kernel.shmmax = 4398046511104
  2. kernel.shmall = 1073741824
  3. kernel.shmmni = 4096

以下是redhat6官方提供的一份安装oracle的文档关于共享内存的部分介绍,如下:

完整版的redhat官方文档可以查看这里

注:需要注意的是free -m命令的输出里也有一项shared,不过通过查看多台主机发现,这项都是0,后来查找资料确认在free命令里共享内存这项已经废弃,没有什么用了。所以共享内存的查看不可以通过该项确认。

四、ipcs与ipcrm

ipcs

ipcs是Linux下显示进程间通信设施状态的工具。可以显示消息队列、共享内存和信号量的信息。对于程序员非常有用,普通的系统管理员一般用不到此指令。

  1. $ipcs -m 查看系统使用的IPC共享内存资源
  2. $ipcs -q 查看系统使用的IPC队列资源
  3. $ipcs -s 查看系统使用的IPC信号量资源
  4. $ipcs -l 查看系统参数配置
  5. 默认不加参数时,使用的参数是 -a (all,显示所有)

输出示例如下:

  1. # ipcs
  2. ------ Message Queues --------
  3. key msqid owner perms used-bytes messages
  4. ------ Shared Memory Segments --------
  5. key shmid owner perms bytes nattch status
  6. 0x6c04c831 294912 zabbix 600 219056 6
  7. 0x0112be9b 458753 root 600 1000 7
  8. 0x0112be9d 491522 root 600 1200712 7
  9. ------ Semaphore Arrays --------
  10. key semid owner perms nsems
  11. 0x7a04c831 1245184 zabbix 600 13
  12. 0x00000000 1802241 apache 600 1
  13. 0x00000000 1835010 apache 600 1

ipcrm

使用ipcrm 命令来清除IPC资源:这个命令同时会将与ipc对象相关联的数据也一起移除。当然,只有root用户,或者ipc对象的创建者才有这项权利;

  1. ipcrm -M shmkey 移除用shmkey创建的共享内存段
  2. ipcrm -m shmid 移除用shmid标识的共享内存段
  3. ipcrm -Q msgkey 移除用msqkey创建的消息队列
  4. ipcrm -q msqid 移除用msqid标识的消息队列
  5. ipcrm -S semkey 移除用semkey创建的信号
  6. ipcrm -s semid 移除用semid标识的信号

ipcs与ipcrm配合清理使用的资源的示例如下:

  1. ipcs -q | awk '{ print "ipcrm -q "$2}' | sh > /dev/null 2>&1;
  2. ipcs -m | awk '{ print "ipcrm -m "$2}' | sh > /dev/null 2>&1;
  3. ipcs -s | awk '{ print "ipcrm -s "$2}' | sh > /dev/null 2>&1;

ipcs的其他应用

使用ipcs还可以用以确认某个用户是否存在消息队列的堆积:

1、查询消息队列

  1. $ipcs -q
  2. ------ Message Queues --------
  3. key msqid owner perms used-bytes messages
  4. 0x49060005 58261504 user1 660 0 0
  5. 0x4f060005 58294273 user1 660 0 0

2、找出messages大于0的队列

  1. $ ipcs -q |grep user1 |awk '{if($5>0) print $0}'
  2. 0x00000000 1071579324 user1 644 1954530 4826
  3. 0x00000000 1071644862 user1 644 1961820 4844
  4. 0x00000000 1071677631 user1 644 1944810 4802
  5. 0x00000000 1071710400 user1 644 1961820 4844

五、为什么需要手动释放共享内存

Linux中通过API函数shmget创建的共享内存一般都是在程序中使用shmctl来释放的,但是有时为了调试程序,开发人员可能通过Ctrl + C等方式发送中断信号来结束程序,此时程序申请的共享内存就不能得到释放,当然如果程序没有改动的话,重新运行程序时仍然会使用上次申请的共享内存,但是如果我们修改了程序,由于共享内存的大小不一致等原因会导致程序申请共享内存错误。因此,我们总是希望每次结束时就能释放掉申请的共享内存。

有两种方法可以用来释放共享内存:

第一种:如果总是通过Crtl+C来结束的话,可以做一个信号处理器,当接收到这个信号的时候,先释放共享内存,然后退出程序。

第二种:不管你以什么方式结束程序,如果共享内存还是得不到释放,那么可以通过linux命令ipcrm shm shmid来释放,在使用该命令之前可以通过ipcs -m命令来查看共享内存。

linux 下共享内存的更多相关文章

  1. linux下共享内存mmap和DMA(直接访问内存)的使用 【转】

    转自:http://blog.chinaunix.net/uid-7374279-id-4413316.html 介绍Linux内存管理和内存映射的奥秘.同时讲述设备驱动程序是如何使用“直接内存访问” ...

  2. 学习笔记:Linux下共享内存的方式实现进程间的相互通信

    一.常用函数 函数系列头文件 #include <sys/types.h> #include <sys/ipc.h> #include <sys/shm.h> ft ...

  3. windows 下共享内存使用方法示例

    windows下共享内存使用方法较 linux 而言微微复杂 示例实现的功能 有一个视频文件,一块内存区域 : 程序 A,将该视频写入该内存区域 : 程序 B,从该内存区域读取该视频 : 代码模块实现 ...

  4. Linux进程间通信—共享内存

    五.共享内存(shared memory) 共享内存映射为一段可以被其他进程访问的内存.该共享内存由一个进程所创建,然后其他进程可以挂载到该共享内存中.共享内存是最快的IPC机制,但由于linux本身 ...

  5. Linux IPC 共享内存

    共享内存 共享内存(shared memory)是最简单的Linux进程间通信方式之一. 使用共享内存,不同进程可以对同一块内存进行读写. 由于所有进程对共享内存的访问就和访问自己的内存空间一样,而不 ...

  6. 转:linux下共享库的注意点之-fpic

    转: http://www.cnblogs.com/leo0000/p/5691483.html linux下共享库的注意点之-fpic 在编译共享库必须加上-fpic.这是为什么呢? 首先看一个简单 ...

  7. Linux下清理内存和Cache方法 /proc/sys/vm/drop_caches

    Linux下清理内存和Cache方法 /proc/sys/vm/drop_caches 频繁的文件访问会导致系统的Cache使用量大增 $ free -m total used free shared ...

  8. Linux下清理内存和Cache方法见下文:

    暂时目前的环境处理方法比较简单: 在root用户下添加计划任务: */10 * * * * sync;echo 3 > /proc/sys/vm/drop_caches; 每十分钟执行一次,先将 ...

  9. Linux下清理内存和Cache方法

    暂时目前的环境处理方法比较简单: 在root用户下添加计划任务: */10 * * * * sync;echo 3 > /proc/sys/vm/drop_caches; 每十分钟执行一次,先将 ...

随机推荐

  1. GCD和NSThread延时执行对比

    1.NSThread: [self performSelector:@selector(performSome:) withObject:self afterDelay:.f]; [[self cla ...

  2. 洛谷P2347 砝码称重

    题目 貌似是某年提高组签到题,六重循环零压力AC,差点怒踩std 但本蒟蒻决定写正解——多重背包,果断20分 原因是写错了状态转移方程...神才知道我咋过的样例和两个测试点 扯远了 多重背包 简单说一 ...

  3. MySQL查询显示连续的结果

    #mysql中 对于查询结果只显示n条连续行的问题# 在领扣上碰到的一个题目:求满足条件的连续3行结果的显示 X city built a new stadium, each day many peo ...

  4. MySQL查询时,查询结果如何按照where in数组排序

    MySQL查询时,查询结果如何按照where in数组排序 在查询中,MySQL默认是order by id asc排序的,但有时候需要按照where in 的数组顺序排序,比如where in的id ...

  5. 【mysql】The server quit without updating PID file

      groupadd mysql useradd -r -g mysql mysql cd /usr/local/mysql chown -R mysql:mysql . scripts/mysql_ ...

  6. python3爬取豆瓣top250电影

    需求:爬取豆瓣电影top250的排名.电影名称.评分.评论人数和一句话影评 环境:python3.6.5 准备工作: 豆瓣电影top250(第1页)网址:https://movie.douban.co ...

  7. 简单了解hash

    hash,译为散列或哈希.就是把任意长度的输入(可变类型除外)经过hash算法,输出成固定长度的输出,该输出就是hash值.哈希值比原有的输出占用空间要小,但是不同的输出可能会hash出一样的值,所以 ...

  8. 持续化集成Jenkins的系统配置

    最近在研究selenium2自动化测试,用到持续化集成jenkins.由于之前仅限于使用,而没有真正动手配置过,所以现在学习从零开始,搭建持续化集成,故而有了这篇博客. 先介绍一下项目持续集成测试,这 ...

  9. MySQL基本命令和常用数据库对象

    MySQL基本命令: 连接远程主机的MySQL服务(为了保证安全性,执行下面命令时,可以省略-p后面的密码,执行命令后系统会提示输入密码) mysql -p 密码 -u 用户名 -h 主机地址 --d ...

  10. Win7通知区域的图标怎么去除?

    由于本人有洁癖,最近在用win7的时候,很收不了已经卸载了的一些软件,在win7右下角的通知区域图标中还留有痕迹,于是上网查找了下解决方案. 用以下方法完美解决问题. 这里依然是以注册表的修改方法为主 ...