2011-09-19 36 views
8

初始化一個二進制信號在它出現在man page,即使你初始化一個信號到一個值:如何在C

sem_init(&mySem, 0, 1); 

它仍可能增加的值大於1,多次調用到

sem_post(&mySem); 

但在這個code example的評論似乎有不同的看法:

sem_init(&mutex, 0, 1);  /* initialize mutex to 1 - binary semaphore */ 

是否可以在C中初始化一個嚴格的二進制信號量?

注意:在這種情況下這樣做而不是使用互斥鎖的原因是sem_post和sem_wait可能會被不同的線程調用。

回答

8

如果您想在Linux上使用嚴格的二進制信號量,我建議您從互斥鎖和條件變量中構建一個。

struct binary_semaphore { 
    pthread_mutex_t mutex; 
    pthread_cond_t cvar; 
    int v; 
}; 

void mysem_post(struct binary_semaphore *p) 
{ 
    pthread_mutex_lock(&p->mutex); 
    if (p->v == 1) 
     /* error */ 
    p->v += 1; 
    pthread_cond_signal(&p->cvar); 
    pthread_mutex_unlock(&p->mutex); 
} 

void mysem_wait(struct binar_semaphore *p) 
{ 
    pthread_mutex_lock(&p->mutex); 
    while (!p->v) 
     pthread_cond_wait(&p->cvar, &p->mutex); 
    p->v -= 1; 
    pthread_mutex_unlock(&p->mutex); 
} 
+0

非常感謝!我最終做了很多。 – austinmarton

+0

'mysem_wait'中'while'循環的意義究竟是什麼?因爲'pthread_cond_wait'在被髮信號後重新獲得互斥信號,並且'pthread_cond_signal'只能解鎖等待條件的單個線程,所以不會有簡單的'if'-語句來完成這項工作嗎? –

+2

@BillDeRose:條件變量會受到虛假喚醒和被盜喚醒的影響。如果你想檢查一個條件,你必須**在循環中使用它們。 –