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。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章