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的主要内容,如果未能解决你的问题,请参考以下文章

使用后如何正确删除信号量?

IPC_RMID 不适用于带有 C++ 的 linux

linux共享内存的控制释放

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)?