正确删除多个进程使用的 SYS V 信号量

Posted

技术标签:

【中文标题】正确删除多个进程使用的 SYS V 信号量【英文标题】:Correctly removing SYS V semaphore used by several processes 【发布时间】:2013-01-16 13:38:49 【问题描述】:

我有一个项目,我必须在其中使用 SYS V 信号量。我有几个进程共享一个信号量(使用相同的键)并使用以下代码对其进行初始化:

bool semaphore_init(semaphore_id_t* sem, int sem_value, key_t key)

    /* Try to get a semaphore, to check if you will be an owner */
    *sem = semget(key, 1, IPC_CREAT | IPC_EXCL | 0666);
    if (*sem == -1)
    
        if (errno == EEXIST)
        
            /* We are not owners, get semaphore without exclusive flag */
            *sem = semget(key, 1, IPC_CREAT | 0666);
            if (*sem == -1) return false;
        
        else return false;
    
    else
    
        /* We are owners, initialize semaphore */
        int return_value = semctl(*sem , 0, SETVAL, sem_value);
        if (return_value == -1) return false;
    

    return true;

我的问题是:当所有使用它的进程都将终止时,我想删除这个信号量。使用:

semctl(*sem, 0, IPC_RMID)

不是一个选项。它立即删除信号量,其他进程得到未定义的行为。我只是找不到使用 SYS V API 的正确方法。

【问题讨论】:

【参考方案1】:

您可以使用引用计数。只需让每个进程在信号量初始化后递增 ref 计数器,并在进程终止时递减它。最后一个将其减为 0 的也会将其删除,或者在主进程知道所有其他进程已终止时将其清理。

您可能还需要另一种锁定机制来同步对引用计数器的访问,您可能会在产生并等待其他进程的主进程中创建/删除它。

此外,如果您的进程可能异常终止,请注意悬空引用。

【讨论】:

问题是图书馆是分散的。正如你所说,我将不得不使用另一个信号量进行引用计数。但谁来释放它?

以上是关于正确删除多个进程使用的 SYS V 信号量的主要内容,如果未能解决你的问题,请参考以下文章

正确销毁命名的 System V 信号量

linux进程间通讯-System V IPC 信号量

Linux进程通信总结

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

Linux进程间通信---信号量

基于信号量的进程同步与互斥