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. 使用shmget()函数创建一个共享内存段,shmget()函数需要指定共享内存的大小、权限和标志等参数。 2. 使用shmat()函数将共享内存段映射到进程的虚拟地址空间中,从而使进程可以访问共享内存。 3. 使用shmdt()函数将共享内存段从进程的虚拟地址空间中分离,从而使得进程无法再访问共享内存。 4. 使用shmctl()函数对共享内存段进行控制,如删除共享内存段等操作。 下面是一个简单的共享内存例子: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/shm.h> #define SHM_SIZE 1024 int main() { key_t key = ftok(".", 'a'); // 生成共享内存的key int shmid = shmget(key, SHM_SIZE, 0666|IPC_CREAT); // 创建共享内存 char *shmaddr = (char *)shmat(shmid, NULL, 0); // 将共享内存映射到进程中 sprintf(shmaddr, "Hello, shared memory!"); // 向共享内存中写入数据 printf("Write data: %s\n", shmaddr); shmdt(shmaddr); // 分离共享内存 return 0; } ``` 这个例子中,我们使用ftok()函数生成共享内存的key,然后使用shmget()函数创建共享内存段,然后使用shmat()函数将共享内存段映射到进程的虚拟地址空间中,并向共享内存中写入数据。最后使用shmdt()函数将共享内存从进程的虚拟地址空间中分离。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值