2013-01-16 60 views
1

我有一个项目,我必须使用SYS V信号量。我有共用一个信号量(使用相同的密钥),并使用此代码初始化几个过程:正确删除几个进程使用的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

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

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

另外,如果您的进程可能异常终止,请留意悬挂引用。

+0

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