linux共享内存的查看与删除
在使用共享内存的程序异常退出时,由于没有释放掉共享内存,在调试时会出现错误。您可以使用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共享内存的查看与删除的更多相关文章
- Linux 程序设计1:深入浅出 Linux 共享内存
笔者最近在阅读Aerospike 论文时,发现了Aerospike是利用了Linux 共享内存机制来实现的存储索引快速重建的.这种方式比传统利用索引文件进行快速重启的方式大大提高了效率.(减少了磁盘 ...
- Linux共享内存的管理
在进程通信应用中会用到共享内存,这就涉及到了IPC,与IPC相关的命令包括:ipcs.ipcrm(释放IPC).IPCS命令是Linux下显示进程间通信设施状态的工具.我们知道,系统进行进程间通信(I ...
- Linux共享内存(一)
inux系统编程我一直看 <GNU/LINUX编程指南>,只是讲的太简单了,通常是书和网络上的资料结合着来掌握才比较全面 .在掌握了书上的内容后,再来都其他资料 . 原文链接 http:/ ...
- 【转载】ipcs与Linux共享内存
一.共享内存相关知识 所谓共享内存,就是多个进程间共同地使用同一段物理内存空间,它是通过将同一段物理内存映射到不同进程的 虚拟空间来实现的.由于映射到不同进程的虚拟空间中,不同进程可以直接使用,不需要 ...
- linux 共享内存shm_open实现进程间大数据交互
linux 共享内存shm_open实现进程间大数据交互 read.c #include <sys/types.h> #include <sys/stat.h> #includ ...
- linux 共享内存
共享内存是最高效的IPC机制,因为它不涉及进程之间的任何数据传输.这种高效带来的问题是,我们必须用其他手段来同步进程对共享内存的访问,否则会产生竞态条件.所以,共享内存通常和其他进程间通信方式一起使用 ...
- Linux共享内存(二)
Linux共享内存编程实例 原文链接:http://blog.csdn.net/pcliuguangtao/article/details/6526119 /*共享内存允许两个或多个进程进程共享同一块 ...
- linux 共享内存 shmat,shmget,shmdt,shmctl
shmget int shmget(key_t key, size_t size, int flag);//开辟一段共享内存 key_t key :标识符的规则() size_t size :共享内存 ...
- linux共享内存简单介绍以及编码演示
共享内存的基本概念 共享内存区是最快的IPC形式.一旦这样的内存映射到共享它的进程的地址空间,这些进程间数据传递不再涉及到内核,换句话说是进程不再通过执行进入内核的系统调用来传递彼此的数据. 下图是共 ...
随机推荐
- android将应用中图片保存到系统相册并显示
我应用到的场景是程序中在视频通讯时截图,将截图保存到本地相册中 /*** @param bmp 获取的bitmap数据 * @param picName 自定义的图片名*/ public static ...
- android 编译错误 Error:(1, 0) Plugin with id 'com.android.application' not found.
在导入一个项目时,由于它本身的gradle版本比较高,你试用比较旧版本的gradle时就报出Plugin with id 'com.android.application' not found.的错误 ...
- C和C++的内存操作小贴士(一):const char*的内存释放问题
C和C++的内存操作一直是困扰开发人员的老问题,基本概念相信老司机们都很清楚了,在这里就不做过多的描述了,只是把在实际开发中可能遇到的一些小问题的案例列举下,供大家参考.“C和C++的内存操作小贴士” ...
- thinkphp 控制器继承
<?php // 本类由系统自动生成,仅供测试用途 class IndexAction extends CateAction { } ?>
- soapui-使用groovy脚本执行用例请求
import com.eviware.soapui.impl.wsdl.testcase.WsdlTestRunContext CURRENT_TESTCASE = testRunner.testCa ...
- CSS之float vs position:absolute
补充:ul 应该设置下 list-style: none; 题外话:看了张鑫旭的视频,这家伙把简单的css玩出了新花样,绝对大神级的存在.膜拜下先~ float的作用前面一章已经说过了,但没考虑过的是 ...
- vi 新建文件后保存文件时遇到的问题:E212: 无法打开并写入文件
问题描述 使用vi编辑器写好内容后保存并退出时遇到以下问题 解决方案 该问题的原因是用户权限不够,因为普通用户用 vi 不能保存文件,需要使用超级用户才可以. 先转换为超级用户:su 再用vi打开文件 ...
- SQL数据查询之——单表查询
一.SQL数据查询的一般格式 数据查询是数据库的核心操作.SQL提供了SELECT语句进行数据查询,其一般格式为: SELECT [ALL | DISTINCT]<目标列表达式>[,< ...
- js作为参数,并且返回值;js的回调模式 callback
有这样一个情景,当我们弹出一个 prompt的时候,要求用户在文本框输入一个文字,然后点击确认,就可以拿到返回值 var temp=prompt("请输入您的名字"); a ...
- erlang的erl文件的编码方式
在数据源头的文件第一行加上%%coding: latin-1