在使用共享内存的程序异常退出时,由于没有释放掉共享内存,在调试时会出现错误。您可以使用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. 关于Unity中的光照(四)

    渲染路径和颜色空间 1:Unity光影效果可以通过设置 渲染路径和颜色空间;2: 渲染路径: 光照到物体表面,物体着色的时候,算上光的颜色的时候有这么几种光照的着色方式,计算着色的方式 forward ...

  2. Mac 系统上安装Lua和SubmlimeText 编译器

    第一步:安装命令 curl -R -O http://www.lua.org/ftp/lua-5.2.3.tar.gz tar zxf lua-5.2.3.tar.gz cd lua-5.2.3 ma ...

  3. 神经网络权值初始化方法-Xavier

    https://blog.csdn.net/u011534057/article/details/51673458 https://blog.csdn.net/qq_34784753/article/ ...

  4. MySQL导入数据错误error: 13 及解决办法

    先说解决办法 将sql文件放到你的账号能够访问的地方!!! 因为我用的grid账号,所以只需要将sql放到 ~grid/ 或者 /tmp等grid能够访问的地方即可. Don't place the ...

  5. doctest初次体验

    测试代码放在两个地方才有效果,一个是模块开头,一个是函数声明语句的下一行 doctest 的概念模型 在python的官方文档中,对doctest是这样介绍的: doctest模块会搜索那些看起来像是 ...

  6. Keystone-all 命令

    本文档介绍Icehouse版keystone-all命令 keystone-all命令在一个进程中同时启动服务和管理API,为openstack提供服务目录,授权和身份认证服务. 用法 $ keyst ...

  7. MySQL查询优化之explain详解

    MySQL explain命令显示了mysql如何使用索引来处理select语句以及连接表.可以帮助选择更好的索引和写出更优化的查询语句. 使用方法,在select语句前加上explain就可以了: ...

  8. linux网络配置练习

    查看网卡是否正常安装 命令:lspci |grep Ether 1.修改网卡配置 命令: vi /etc/sysconfig/network-scripts/ifcfg-eth0 DEVICE=eth ...

  9. Java基础--深克隆补充

    深克隆文章很多,这里推荐Java提高篇--对象克隆(复制). 以上文章条理清晰,一目了然,但最近在项目中碰到的实际问题是,所要克隆的对象是加上子类父类共计207个,无论用上述两种方式的哪一种,都要一一 ...

  10. java rpc

    一.简介 Hessian和Burlap是由Caucho Technology提供的基于HTTP协议的轻量级远程服务解决方案.他们都致力于借助尽可能简单那的API和通信协议来简化Web服务.    He ...