一、共享内存相关知识

所谓共享内存,就是多个进程间共同地使用同一段物理内存空间,它是通过将同一段物理内存映射到不同进程的 虚拟空间来实现的。由于映射到不同进程的虚拟空间中,不同进程可以直接使用,不需要像消息队列那样进行复制,所以共享内存的效率很高。共享内存可以通过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命令来查看共享内存。

 

【转载】ipcs与Linux共享内存的更多相关文章

  1. Linux 程序设计1:深入浅出 Linux 共享内存

    笔者最近在阅读Aerospike 论文时,发现了Aerospike是利用了Linux 共享内存机制来实现的存储索引快速重建的.这种方式比传统利用索引文件进行快速重启的方式大大提高了效率.(减少了磁盘 ...

  2. Linux共享内存的管理

    在进程通信应用中会用到共享内存,这就涉及到了IPC,与IPC相关的命令包括:ipcs.ipcrm(释放IPC).IPCS命令是Linux下显示进程间通信设施状态的工具.我们知道,系统进行进程间通信(I ...

  3. linux 共享内存shm_open实现进程间大数据交互

    linux 共享内存shm_open实现进程间大数据交互 read.c #include <sys/types.h> #include <sys/stat.h> #includ ...

  4. linux 共享内存

    共享内存是最高效的IPC机制,因为它不涉及进程之间的任何数据传输.这种高效带来的问题是,我们必须用其他手段来同步进程对共享内存的访问,否则会产生竞态条件.所以,共享内存通常和其他进程间通信方式一起使用 ...

  5. Linux共享内存(二)

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

  6. 关于linux 共享内存查看已经完整释放

    完整删除共享内存脚本 #!/bin/sh function rmshm() { zero_status=`ipcs -m|awk '{print $6}'|grep -w 0|wc -l` if [ ...

  7. Linux共享内存(一)

    inux系统编程我一直看 <GNU/LINUX编程指南>,只是讲的太简单了,通常是书和网络上的资料结合着来掌握才比较全面 .在掌握了书上的内容后,再来都其他资料 . 原文链接 http:/ ...

  8. Linux共享内存使用常见陷阱与分析

    所谓共享内存就是使得多个进程可以访问同一块内存空间,是最快的可用IPC形式.是针对其他通信机制运行效率较低而设计的.往往与其它通信机制,如 信号量结合使用,来达到进程间的同步及互斥.其他进程能把同一段 ...

  9. linux共享内存的查看与删除

    在使用共享内存的程序异常退出时,由于没有释放掉共享内存,在调试时会出现错误.您可以使用shell命令来查看与释放已经分配的共享内存,下面将详细说明如何进行查看和释放分配的共享内存的方法. 预备知识 L ...

随机推荐

  1. centos yum安装ffmpeg

    ffmpeg是一个重要的应用软件,用于执行与视频文件转换成不同的视频流格式的视频站点,能够安装在linux系统上来使用 (一)安装编译环境  #yum install -y automake auto ...

  2. RedHat Linux AS4 DNS 配置

     RedHat Linux AS4 DNS配置   检查当前系统中安装 DNS功能组件bind情况 [root@svr01 /]# rpm -qa|grep bind* ypbind-1.17.2 ...

  3. Janus 二元神漏洞测试

    同步发表于:http://blog.hacktons.cn/2017/12/25/janus-demo/ 背景 12月9号,Andorid对外曝光了一个名为Janus的重量级系统漏洞CVE-2017- ...

  4. Spring依赖注入原理

    接触过spring 的同学应该都知道依赖注入,依赖注入又称控制反转,其内涵就是,将创建某个bean的控制权力,由原来需要引用这个bean的bean转移(反转)到外部的spring IOC容器,由IOC ...

  5. 在Eclipse中如何关联源代码

    我们就以Struts2框架为例,展示在Eclipse中如何关联源代码.例如,在Struts2框架的学习中,我们有时需要查看ActionSupport这个类的源码,这个时候就要在Eclipse中关联源代 ...

  6. Intellijidea建javaWeb以及Servlet简单实现

    一.创建并设置javaweb工程1.创建javaweb工程File --> New --> Project... 点击Project后出现如下界面,选择Java Enterprise,选中 ...

  7. pytho核心编程2-1中代码运行问题

    书籍是<python核心编程>第三版,学习环境py3.6 2-1 时间戳服务器 附源代码: from socket import * from time import ctime HOST ...

  8. 工作随笔——selenium支持post请求,支持自定义header

    背景: 最近在写一个小程序,发现博主所在的地区访问该网站时有防ddos功能验证导致程序不能正常工作. 经过试验发现可以用国外代理ip解决这个问题,但是程序走代理访问延迟高且不稳定. 思路: selen ...

  9. vue-cli+webpack打包配置

    vue-cli+webpack打包配置 一: 目录结构: ├── README.md ├── build │ ├── build.js │ ├── check-versions.js │ ├── ut ...

  10. NodeJs学习笔记(五)---单元测试补充

    今天早上继续研究Mocha,忽然发现一个问题,我的大部分程序都是需要登录验证的,所以需要预先登录之后才能进行下一步测试,就开始在网上找答案,发现没有这种资料,很疑惑,最后发现其实是自己太笨了,因为这个 ...