如何删除共享内存段后某些程序在退出之前无法从中分离?

时间:2014-07-23 08:56:08

标签: c linux

我在linux系统上学习ipc。在我使用共享内存尝试了几个示例程序之后,我在linux系统上发现了一些待处理的共享内存部分,并且它们无法删除。

我重新启动机器,它们仍然存在。

我写了一个试图删除它们的程序,但这也不行。因为系统认为某些程序仍然附加了这些共享内存段(参见nattch专栏)。

有谁知道如何删除它们。感谢。

[root@luaDevelopment 17.2UNIXDomainSocket]# ipcs -m

------ Shared Memory Segments --------
key        shmid      owner      perms      bytes      nattch     status
0x00000000 98304      root       600        393216     2          dest
0x00000000 131073     root       600        393216     2          dest
0x00000000 163842     root       600        393216     2          dest
0x00000000 196611     root       600        393216     2          dest
0x00000000 229380     root       600        393216     2          dest
0x00000000 262149     root       600        393216     2          dest
0x00000000 294918     root       600        393216     2          dest
0x00000000 327687     root       600        393216     2          dest
0x00000000 360456     root       600        393216     2          dest
0x00000000 393225     root       600        393216     2          dest
0x00000000 425994     root       600        393216     2          dest
0x00000000 458763     root       600        393216     2          dest

clearShm.c

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/shm.h>

int main(int argc, char *argv[])
{
    int shmIDArray[]={98304,131073,163842,196611,229380,262149,294918,327687,360456,393225,425994,458763};
    for(int i=0; i<sizeof(shmIDArray)/sizeof(int); i++)
    {
        if(shmctl(shmIDArray[i], IPC_RMID, NULL) < 0)
        {
            fprintf(stderr, "remove error for shmid=%d: %s\n", shmIDArray[i], strerror(errno));
        }else{
            printf("delete %d\n", shmIDArray[i]);
        }
    }
    return 0;
}
上面程序的

shell输出

[root@luaDevelopment 17.2UNIXDomainSocket]# ./clearShm
delete 98304
delete 131073
delete 163842
delete 196611
delete 229380
delete 262149
delete 294918
delete 327687
delete 360456
delete 393225
delete 425994
delete 458763

=============================================

今天我启动计算机,发现这些共享内存段已经消失。在我昨天关闭计算机之前他们还在那里。而且我不知道为什么。

1 个答案:

答案 0 :(得分:1)

Wel首先为您的代码配备以下详细信息:

如果程序出现故障或正常退出,您可以在代码中使用int shmctl(int shmid, int cmd, struct shmid_ds *buf);从系统中删除共享内存段。

但是,您应该查看IPC_RMID手册页的shmctl部分。在您尝试删除共享内存区域之前,man页面状态下面要满足的条件:

  

IPC_RMID 标记要销毁的细分受众群。 该段仅在最后一个进程分离后才会被实际销毁(即   什么时候                    相关结构shmid_ds的shm_nattch成员为零)。呼叫者必须是所有者或创建者,或者是   privi-                    leged。如果某个段已标记为要销毁,那么shm_perm.mode的(非标准)SHM_DEST标志   在该领域                    将设置IPC_STAT检索的关联数据结构。

     

调用者必须确保段最终被销毁;否则其故障的页面将保留   记忆                    或交换。

     

另请参阅proc(5)中/ proc / sys / kernel / shm_rmid_forced的描述。

您可以参考以下代码:

if(-1 == (shmctl(shmid, IPC_STAT, &shmid_ds)))
{   
    perror("shmctl");
}   

if(-1 == (shmctl(shmid, IPC_RMID, &shmid_ds)))
{   
    perror("shmctl");
}   

要删除现有的共享内存段,最好在问题的评论中使用ipcrm -m <shmid>。您可以创建一个可以删除所有段的shell脚本。