条件变量信令

时间:2012-12-08 08:19:13

标签: synchronization pthreads condition-variable

在此链接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);
}

2 个答案:

答案 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()是一种优化,您应该仔细分析算法在使用时是否仍然正确。