在此链接here中,在增量函数中,在实际递增计数(从零开始)之前发出条件变量信号。递增计数后是否应该调用信号?或者,在increment_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);
}
答案 0 :(得分:2)
由于互斥锁,如果在信号之前或之后执行此操作无关紧要,因为在互斥锁解锁之前无法读取变量。
答案 1 :(得分:1)
作为Troy says,在递增counter
之前发信号通知条件变量很好,因为这些操作都是在保持互斥锁的情况下完成的。
但是,如果多个线程可以在decrement_count()
中等待,则此代码确实存在一个微妙的错误。考虑两个线程在pthread_cond_wait()
中被暂停的情况,count == 0
。现在,increment_count()
连续两次调用(可能由同一个线程) - count
增加到2
,应该如此,但条件变量只发出一次信号。这意味着只有一个的等待线程被唤醒,而另一个将无限期地等待,即使counter
非零。
可以通过多种方式修复此错误:
pthread_cond_signal()
替换为pthread_cond_broadcast()
中的increment_count()
;或pthread_cond_signal()
中的increment_count()
;或pthread_cond_signal()
递减后,如果count
非零,请致电decrement_count()
。一般情况下,请记住,使用pthread_cond_signal()
代替pthread_cond_broadcast()
是一种优化,您应该仔细分析算法在使用时是否仍然正确。