2012-12-08 25 views
0

在此链接here中,在递增函数中,条件变量在实际递增计数(从零开始)之前发出信号。信号在递增计数之后是否应该被调用?或者在decrement_count函数中的等待调用不会返回,直到在increment_function中释放互斥量为止?条件变量信号发送

pthread_mutex_t count_lock; 
pthread_cond_t count_nonzero; 
unsigned count; 

decrement_count() 
{ 
    pthread_mutex_lock(&count_lock); 
    while (count == 0) 
     pthread_cond_wait(&count_nonzero, &count_lock); 
    count = count - 1; 
    pthread_mutex_unlock(&count_lock); 
} 

increment_count() 
{ 
    pthread_mutex_lock(&count_lock); 
    if (count == 0) 
     pthread_cond_signal(&count_nonzero); 
    count = count + 1; 
    pthread_mutex_unlock(&count_lock); 
} 

回答

2

因为互斥锁,如果你之前或之后的信号做到这一点,因为变量不能被读取,直到互斥量被释放没关系。

+0

因此,递减函数中的等待调用不会返回,直到条件变量发出信号并且互斥量在增量函数中解锁为止? – Kamal

+0

正确的是,当进入cond等待时,它释放互斥锁,当它再次唤醒时,它会再次锁定互斥锁,因为互斥锁被锁定在缓存函数中,cond不会被唤醒直到其解锁。 – goji

1

因为Troy says,在增加counter之前发信号通知条件变量是好的,因为这些操作都是在保持互斥体的情况下完成的。

但是,如果多个线程可以在decrement_count()中等待,此代码确实有一个微妙的错误。考虑在pthread_cond_wait()中挂起两个线程的情况,count == 0。现在,increment_count()被连续调用两次(也许是同一个线程) - count会增加到2,因为它应该是这样,但条件变量只发送一次信号。这意味着等待线程只有一个被唤醒,而另一个将无限期地等待,即使counter非零。

此错误可以固定在几个方面:

  • increment_count()pthread_cond_broadcast()取代pthread_cond_signal();或
  • 无条件地拨打在increment_count();或
  • 请致电pthread_cond_signal()如果countdecrement_count()递减后不为零。

在一般情况下,请记住,使用pthread_cond_signal()代替pthread_cond_broadcast()是一个优化的,你应该仔细分析使用时的算法是否仍然正确。