shmctl 和 semctl 不删除 ipc
Posted
技术标签:
【中文标题】shmctl 和 semctl 不删除 ipc【英文标题】:shmctl and semctl do not remove the ipc 【发布时间】:2014-11-18 09:43:11 【问题描述】:我正在创建共享内存段和信号量来锁定和解锁它们,并且在我的程序结束时它们不会被删除。我删除它们的代码如下
if ((shmdt(shared_memory)) == -1)
fprintf(stderr, "shmdt failed\n");
if ((shmctl(shmid, IPC_RMID, 0) )== -1)
fprintf(stderr, "shmctl(IPC_RMID) failed\n");
对于信号量
if((semctl(sid, 0, IPC_RMID, 0))==-1)
fprintf(stderr, "semctl(IPC_RMID) failed\n");
它们都没有进入 if 语句,这意味着它们不会返回 -1
。
但是在我在终端中运行ipcs
之后,它们仍然存在,并且带有正确的密钥(我在代码中设置的那个)。
我还注意到,shmid
在创建并附加到共享内存段之后是 0。这是为什么呢?除了删除 ipcs,我的代码一切正常。
现在我知道要真正删除共享内存,所有附加到它的进程
必须分离。我在我的应用程序完成后立即运行ps u
,并且它创建的所有子进程都没有运行,因此没有僵尸进程,它们在代码中的分离方式与父进程分离的方式相同。
所以我的问题是,发生了什么事?为什么不删除?
【问题讨论】:
您是否尝试使用shmctl()
和IPC_STAT 作为命令打印出shmid_ds
结构?在执行IPC_RMID
之前,您可以检查shmid_ds
中的shm_nattch
是否为0。如果不为0,则表示还有一些进程附加。
@SSC 您可以将其设置为答案以便我接受吗?这帮助我发现了问题。我留下了一个进程,我无法通过 ps -a 找到它,因为它只是一瞬间的僵尸,但这足以弄乱我的结果
您可能应该使用 POSIX 共享内存(参见 shm_overview(7))和信号量(参见 sem_overview(7))。 SysV 几乎已被弃用。
@BasileStarynkevitch 将在未来进行调查
【参考方案1】:
请尝试使用shmctl()
和IPC_STAT
作为命令打印出shmid_ds
结构。在执行IPC_RMID
之前,您可以检查shmid_ds
中的shm_nattch
是否为0
。如果不为0,则表示还有一些进程附加。
【讨论】:
以上是关于shmctl 和 semctl 不删除 ipc的主要内容,如果未能解决你的问题,请参考以下文章
Linux C语言进程间通信 共享内存(Shared Memory)shmget()shmat()shmdt()shmctl() ipcs -mipcrm -m
Linux C语言进程间通信 共享内存(Shared Memory)shmget()shmat()shmdt()shmctl() ipcs -mipcrm -m
更好的 Java IPC@Linux 策略:(a) /dev/shm 上的 java.nio 文件 API 或 (b) JNI 到 shmctl(2)?