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