【问题标题】:condition variables signaling条件变量信号
【发布时间】:2012-12-08 08:19:12
【问题描述】:

在此链接here 中,在增量函数中,条件变量在实际增加计数(从零开始)之前发出信号。增加计数后是否不应该调用信号?还是在 increment_function 中释放 mutex 之前,decrement_count 函数中的等待调用不会返回?

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);
}

【问题讨论】:

    标签: synchronization pthreads condition-variable


    【解决方案1】:

    因为互斥锁,不管是在信号之前还是之后做都没有关系,因为在互斥锁解锁之前无法读取变量。

    【讨论】:

    • 所以在递减函数中的等待调用不会返回,直到条件变量发出信号并且互斥锁在递增函数中解锁?
    • 对了,当进入cond wait时,它解锁了mutex,当它重新唤醒时,它再次锁定了mutex,所以因为在增量函数中锁住了mutex,所以cond不会醒来直到解锁。
    【解决方案2】:

    作为Troy says,在递增counter 之前向条件变量发出信号是可以的,因为这些操作都是在持有互斥体的情况下完成的。

    但是,如果多个线程可以在decrement_count() 中等待,则此代码确实存在一个细微的错误。考虑两个线程在pthread_cond_wait() 中挂起的情况,count == 0。现在,increment_count() 被连续调用两次(可能由同一个线程调用)——count 应该是递增到2,但条件变量只发出一次信号。这意味着只有 一个 等待线程被唤醒,而另一个将无限期等待,即使 counter 不为零。

    可以通过多种方式修复此错误:

    • increment_count() 中将pthread_cond_signal() 替换为pthread_cond_broadcast();或
    • increment_count()中无条件调用pthread_cond_signal();或
    • 如果countdecrement_count() 中递减后非零,则调用pthread_cond_signal()

    一般情况下,请记住使用pthread_cond_signal()而不是pthread_cond_broadcast()是一种优化,使用时应仔细分析算法是否仍然正确。

    【讨论】:

      猜你喜欢
      • 2011-03-31
      • 2011-10-19
      • 1970-01-01
      • 1970-01-01
      • 2020-07-12
      • 2010-10-30
      • 2011-07-07
      • 2011-07-18
      • 1970-01-01
      相关资源
      最近更新 更多