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

预备知识

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

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

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

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

共享内存查看

使用ipcs命令,不加如何参数时,会把共享内存、信号量、消息队列的信息都打印出来,如果只想显示共享内存信息,使用如下命令:

[root@localhost ~]# ipcs -m

------ Shared Memory Segments --------

key        shmid      owner      perms      bytes      nattch     status

0x00000000 1867776    root      600        393216     2          dest

0x00000000 1900545    root      600        393216     2          dest

0x00030021 1703938    zc        666        131104     1

0x0003802e 1736707    zc        666        131104     1

0x00030004 1769476    zc        666        131104     1

0x00038002 1802245    zc        666        131104     1

0x00000000 1933318    root      600        393216     2          dest

0x00000000 1966087    root      600        393216     2          dest

0x00000000 1998856    root      600        393216     2          dest

0x00000000 2031625    root      600        393216     2          dest

0x00000000 2064394    root      600        393216     2          dest

0x0014350c 2261003    cs        666        33554432   2

0x00000000 2129932    root      600        393216     2          dest

0x00000000 2162701    root      600        393216     2          dest

0x00143511 395837454  root      666        1048576    1

其中:

第一列就是共享内存的key;

第二列是共享内存的编号shmid;

第三列就是创建的用户owner;

第四列就是权限perms;

第五列为创建的大小bytes;

第六列为连接到共享内存的进程数nattach;

第七列是共享内存的状态status。其中显示“dest”表示共享内存段已经被删除,但是还有用户在使用它,当该段内存的mode字段设置为 SHM_DEST时就会显示“dest”。当用户调用shmctl的IPC_RMID时,内存先查看多少个进程与这个内存关联着,如果关联数为0,就会销 毁这段共享内存,否者设置这段内存的mod的mode位为SHM_DEST,如果所有进程都不用则删除这段共享内存。

共享内存释放

要释放共享内存,需要使用ipcrm命令,使用shmid作为参数,shmid在ipcs命令中会有输出,下面的命令可以释放所有已经分片的共享内存:

# ipcrm <shmid>

# ipcs -m | awk ‘$2 ~/[0-9]+/ {print $2}’ | while read s; do sudo ipcrm –m $s; done

注:Linux中vi使用Ctrl+s来锁定,需要使用Ctrl+q来解除锁定。

使用Python编写的rmsharemem.py脚本如下:

# -*- coding: utf-8 -*-

# Remove the share memory

import os

import sys

import getopt

def usage():

print "usage: python rmsharemem.py -h -o <owner> -s size <shmid list>"

print "  -h show help information"

print "  -o <owner> the owner create share memory need to delete"

print "  -s <size>  the share memory size"

print "  <shmid list> the shmid list need to delete"

def getsharemem():

sharemap = {}

fp = os.popen('ipcs -m')

lines = fp.readlines()

for l in lines:

if not l.startswith('0x'):

continue

s = l.split()

if sharemap.has_key(s[2]):

sharemap[s[2]].append(s)

else:

sharemap[s[2]] = [s]

#print 'Share memory map:\n', sharemap

return sharemap

if __name__ == "__main__":

opts, args = getopt.getopt(sys.argv[1:], "o:hs:")

# opts is the parameter with options

# args is the parameter no ptions

owner = None

size = 0

for o, p in opts:

if o == '-h':

usage()

sys.exit(0)

elif o == '-o':

owner = p

elif o == '-s':

size = p

if not owner:

val = raw_input("Are you sure to remove all share memory?(yes/no)");

if (val <> "yes"):

usage()

sys.exit(0)

count = 0

total = 0

if len(args) > 0:

for shmid in args:

cmd = 'ipcrm -m %s' % shmid

print 'execute command: %s' % cmd

ret = os.system(cmd)

total += 1

if ret == 0:

count += 1

print 'remove %s shared memory success' % shmid

else:

print 'remove %s shared memory failed' % shmid

else:

shmmap = getsharemem()

for o, l in shmmap.items():

if owner and o <> owner:

continue

for p in l:

total += 1

if size and size <> p[4]:

continue

cmd = 'ipcrm -m %s' % p[1]

print 'execute command: %s' % cmd

ret = os.system(cmd)

if ret == 0:

count += 1

print 'remove %s shared memory success' % p[1]

else:

print 'remove %s shared memory failed' % p[1]

print 'total share memory number = %s' % total

print 'remove success number = %s' % count

sys.exit(0)

共享内存大小修改

使用下面的命令查看共享内存的大小:

# cat /proc/sys/kernel/shmmax

修改共享内存大小:

临时修改:在root用户下执行# echo 268435456 > /proc/sys/kernel/shmmax把共享内存大小设置为256MB;

永久修改:在root用户下修改/etc/rc.d/rc.local文件,加入下面一行:

echo 268435456 > /proc/sys/kernel/shmmax

即可每次启动时把共享内存修改为256MB。

linux共享内存的查看与删除的更多相关文章

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

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

  2. Linux共享内存的管理

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

  3. Linux共享内存(一)

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

  4. 【转载】ipcs与Linux共享内存

    一.共享内存相关知识 所谓共享内存,就是多个进程间共同地使用同一段物理内存空间,它是通过将同一段物理内存映射到不同进程的 虚拟空间来实现的.由于映射到不同进程的虚拟空间中,不同进程可以直接使用,不需要 ...

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

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

  6. linux 共享内存

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

  7. Linux共享内存(二)

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

  8. linux 共享内存 shmat,shmget,shmdt,shmctl

    shmget int shmget(key_t key, size_t size, int flag);//开辟一段共享内存 key_t key :标识符的规则() size_t size :共享内存 ...

  9. linux共享内存简单介绍以及编码演示

    共享内存的基本概念 共享内存区是最快的IPC形式.一旦这样的内存映射到共享它的进程的地址空间,这些进程间数据传递不再涉及到内核,换句话说是进程不再通过执行进入内核的系统调用来传递彼此的数据. 下图是共 ...

随机推荐

  1. 【转】常用 Microsoft .NET Framework 各版本下載網址列表

    研究] 常用 Microsoft .NET Framework 各版本下載網址列表 2014-05-23 僅列常用的 (IA64, Beta, hotfix, ... 不列) Microsoft .N ...

  2. 电源PI相关知识讲解

    电源层与地线层的谐振控制 一旦PCB的电源与地层的形状.距离以及中间介质定下来以后,发生谐振的频率也就定下来了. 采用LC等效电路,不考虑PCB上的损耗,而这些损耗往往在高频影响尤为明显,例如趋肤效应 ...

  3. [转]Idea2016 使用Maven配置简单Web项目(受益比较多的一篇)

    最近被同事一直吵着用Idea写Java,于是偷偷的去试用了一下Idea.确实不错,无论界面还是智能提醒都是蛮符合我的使用习惯,但是刚从Eclipse出来,使用Idea还是不太习惯的.所以这里写出来,供 ...

  4. 将项目安装到Maven本地资源库

    在Maven中,可以使用“mvn install”打包项目,并自动部署到本地资源库,让其他开发人员使用它. mvn install 注意,当“install”在执行阶段,上述所有阶段 “validat ...

  5. e788. 取消JSpinner的键盘编辑能力

    // Create a nummber spinner JSpinner spinner = new JSpinner(); // Disable keyboard edits in the spin ...

  6. Python——greenlet

    目录 1. 介绍 2. 父greenlet 3. 实例化 4. 在greenlets间切换 5. 垂死的greenlets 6. greenlet的方法和属性 7. greenlets和Python线 ...

  7. 植物 miRNA 研究

    相比动物miRNA 而言, 植物miRNA 的研究相对较少. 植物miRNA 相比动物miRNA , 有以下特点: 1) 植物miRNA 的长度为 21 nt 左右, 动物miRNA 长度在 22 ~ ...

  8. 带有Header的SOAP 请求

    package demo.test; import javax.xml.bind.JAXBElement; import javax.xml.namespace.QName; import org.t ...

  9. js pjax 和window.history.pushState,replaceState

    原文:http://blog.linjunhalida.com/blog/pjax/ github:https://github.com/defunkt/jquery-pjax 什么是pjax? 现在 ...

  10. excel做回归分析的应用【风控数据分析】

    方法1     统计逻辑:统计一个loginname的所有去重的通讯录数C,统计这个Loginname对应的每个设备对应的通讯录c1,c2,c3…cn; X=(c1/c+c2/c+c3/c+….cn/ ...