C 如何删除共享内存段后,一些程序未能从它退出前分离?

C 如何删除共享内存段后,一些程序未能从它退出前分离?,c,linux,C,Linux,我正在linux系统上学习ipc。在我试用了几个使用共享内存的示例程序之后,我发现一些共享内存部分在我的linux系统上挂起,它们无法删除 我重新启动机器,它们仍然存在 我写了一个程序试图删除它们,但这也不起作用。因为系统认为有一些程序仍然连接着这些共享内存段(参见Natch专栏) 有人知道如何删除它们吗。谢谢 [root@luaDevelopment 17.2UNIXDomainSocket]# ipcs -m ------ Shared Memory Segments -------- k

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

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

我写了一个程序试图删除它们,但这也不起作用。因为系统认为有一些程序仍然连接着这些共享内存段(参见Natch专栏)

有人知道如何删除它们吗。谢谢

[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;
}
=============================================


今天我启动电脑,发现这些共享内存段不见了。就在昨天我关闭电脑之前,它们还在那里。我也不知道为什么。

我们将首先为您的代码提供以下详细信息:

您可以使用
intshmctl(intshmid,intcmd,structshmid\u ds*buf)
在您的代码中,以在程序失败或正常退出时从系统中删除共享内存段

但是,您应该查看
shmctl
手册页的
IPC\u RMID
部分<代码>人页面在尝试删除共享内存间隔之前,请说明以下要满足的条件:

IPC\u RMID标记要销毁的段该段只有在最后一个进程将其分离(即。, 什么时候 关联结构shmid\u ds的shm\u natch成员为零)。调用方必须是所有者或创建者,或者是 私人 合法的。如果段已标记为销毁,则SHM_perm.mode的(非标准)SHM_DEST标志 野外 将设置IPC_STAT检索的相关数据结构

调用者必须确保一个段最终被销毁;否则,在中出错的页面将保留在中 记忆 或者交换

另请参见proc(5)中强制的/proc/sys/kernel/shm\u rmid\u的描述

例如,您可以参考以下代码:

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

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

要删除现有的共享内存段,最好使用
ipcrm-m
,这在问题的评论中已经说过。您可以制作一个可以删除所有段的shell脚本。

问得好。您无法真正知道何时不再需要shm,但也许cron作业应该查看“最后访问”时间并定期清理?您好,@KerrekSB,谢谢您的评论。我知道这些shm已经不再使用了。它们是由几天前执行的一些实验程序创建和附加的。这些程序在退出之前没有调用shmdt,它们现在也没有运行。是的,我理解,但我想我们正在寻找一个通用的解决方案。对于一次性工作,您可以使用
ipcrm
。谢谢。我在手册页中查找了ipcrm。
ipcrm-m shmid
在执行最后一次分离操作后标记要删除的shm。但我不能执行分离操作。@KerrekSB
if(-1 == (shmctl(shmid, IPC_STAT, &shmid_ds)))
{   
    perror("shmctl");
}   

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