IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    清除共享内存

    rock发表于 2013-04-17 09:33:18
    love 0

    来自:http://blog.csdn.net/fan_hai_ping/article/details/6682046


    在unix/linux下,经常有因为共享内存、信号量,队列等共享信息没有干净地清楚而引起一些问题。

    查看共享信息的内存的命令是ipcs [-m|-s|-q]。

    默认会列出共享内存、信号量,队列信息,-m列出共享内存,-s列出共享信号量,-q列出共享队列。

    怎样清除呢?
    清楚命令是ipcrm [-m|-s|-q] id。
    -m 删除共享内存,-s删除共享信号量,-q删除共享队


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

    # ipcs -m | awk '$2 ~/[0-9]+/ {print $2}' | while read s; do 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 -s size "

    print " -h show help information"

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

    print " -s the share memory size"

    print " 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。




沪ICP备19023445号-2号
友情链接