我在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
=============================================
今天我启动计算机,发现这些共享内存段已经消失。在我昨天关闭计算机之前他们还在那里。而且我不知道为什么。
答案 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脚本。