Synchronization 条件变量信号

Synchronization 条件变量信号,synchronization,pthreads,condition-variable,Synchronization,Pthreads,Condition Variable,在这个链接中,在递增函数中,在实际递增计数(从零开始)之前,先发出条件变量的信号。增加计数后是否不调用该信号?或者在递增计数函数中释放互斥量之前,递减计数函数中的等待调用不会返回 pthread_mutex_t count_lock; pthread_cond_t count_nonzero; unsigned count; decrement_count() { pthread_mutex_lock(&count_lock); while (count == 0)

在这个链接中,在递增函数中,在实际递增计数(从零开始)之前,先发出条件变量的信号。增加计数后是否不调用该信号?或者在递增计数函数中释放互斥量之前,递减计数函数中的等待调用不会返回

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

由于互斥锁,在信号之前或之后执行该操作无关紧要,因为在互斥锁解锁之前无法读取变量。

由于互斥锁,在信号之前或之后执行该操作无关紧要,因为在互斥锁解锁之前无法读取变量。

As,在递增
计数器
之前发送条件变量是可以的,因为这些操作都是在保持互斥锁的情况下完成的

但是,如果多个线程可以在
decrement\u count()
中等待,则此代码确实存在一个微妙的错误。考虑两个线程在<代码> pthRead CONDYWAITE()/<代码>中暂停的情况,使用<代码>计数=0 。现在,
increment\u count()。这意味着只有一个等待线程被唤醒,而另一个线程将无限期地等待,即使
计数器
为非零

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

  • 增量计数()中的
    pthread_cond_signal()
    替换为
    pthread_cond_broadcast()
    ;或
  • 无条件调用
    increment\u count()
    中的
    pthread\u cond\u signal()
    ;或
  • 如果
    计数在
    递减计数()中递减后非零,则调用
    pthread\u cond\u signal()
一般来说,请记住使用
pthread\u cond\u signal()
而不是
pthread\u cond\u broadcast()
是一种优化,使用时应仔细分析算法是否仍然正确。

As,在递增
计数器之前发送条件变量是可以的,因为这些操作都是在保持互斥锁的情况下完成的

但是,如果多个线程可以在
decrement\u count()
中等待,则此代码确实存在一个微妙的错误。考虑两个线程在<代码> pthRead CONDYWAITE()/<代码>中暂停的情况,使用<代码>计数=0 。现在,
increment\u count()。这意味着只有一个等待线程被唤醒,而另一个线程将无限期地等待,即使
计数器
为非零

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

  • 增量计数()中的
    pthread_cond_signal()
    替换为
    pthread_cond_broadcast()
    ;或
  • 无条件调用
    increment\u count()
    中的
    pthread\u cond\u signal()
    ;或
  • 如果
    计数在
    递减计数()中递减后非零,则调用
    pthread\u cond\u signal()

通常,请记住,使用
pthread\u cond\u signal()
而不是
pthread\u cond\u broadcast()
是一种优化,在使用该算法时,您应该仔细分析其是否仍然正确。

因此,在条件变量发出信号且互斥锁在增量函数中解锁之前,递减函数中的等待调用不会返回?正确,当输入cond wait时,它解锁互斥锁,当它唤醒时,它再次锁定互斥锁,因此,由于互斥锁在递增函数中被锁定,cond在其解锁之前不会被唤醒。因此,递减函数中的等待调用在条件变量发出信号且互斥锁在递增函数中被解锁之前不会返回?正确,当输入cond wait时,它解锁互斥锁,当它被唤醒时,它再次锁定互斥锁,因此,由于互斥锁是在递增函数中锁定的,因此cond在其解锁之前不会唤醒。