我有一个项目,我必须使用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的正确方法。
答案 0 :(得分:0)
您可以使用引用计数。只需让每个进程在信号量init之后递增ref计数器,并在进程终止时递减它。将它减少为0的最后一个也将删除它,或者当它知道所有其他进程已经终止时让主进程清理它。
您可能还需要另一种锁定机制来同步对引用计数器的访问,您可能会在生成并等待其他进程的主进程中创建/删除它。
另外,如果您的进程异常终止,请注意悬空引用。