【问题标题】:pthread_cond_broadcast before and after one pthread_mutex_unlockpthread_cond_broadcast 在一个 pthread_mutex_unlock 之前和之后
【发布时间】:2021-05-25 05:13:12
【问题描述】:

对于下面的代码,在执行第二个 cond_broadcast 时互斥锁将不可用(假设多个线程已经在等待条件)。在这种情况下,广播是选择线程(等待条件)将互斥锁交给并等待互斥锁被其他线程解锁还是忽略第二个 cond_broadcast?

void* func(void* arg){
pthread_mutex_lock(&m);
while(condition){
pthread_cond_wait(&c,&m);
}
pthread_cond_broadcast(&c);
pthread_mutex_unlock(&m);
pthread_cond_broadcast(&c);
}

【问题讨论】:

  • 只有在广播时刻等待条件的线程才会注意到广播。您通常会在持有互斥锁时发出信号/广播,然后释放它。等待线程应该只在他们持有互斥锁时等待,在检查条件之后。如果任何其他线程可能正在等待,它们还应该在释放互斥锁之前发出条件信号。
  • 在没有互斥锁时调用 pthread_cond_broadcast() 仍然会进行广播,但如果线程有互斥锁但在执行时没有等待条件,则可能会错过广播广播,所以这样做不好。仅在互斥锁锁定时发出信号可确保在另一个线程持有互斥锁时无法发送信号,除非该线程正在等待信号。
  • 谢谢!只是一个后续问题:是否有可能让两个线程在相同的条件下等待但不同的互斥锁,例如。 pthread_cond_wait(&c,&m1) 和 pthread_cond_wait(&c,&m2)?如果可能,那么来自第三个线程的 pthread_cond_broadcast(&c) 是否会唤醒两个线程并且它们会同时获取互斥锁(假设不存在其他线程)?
  • 有可能,但不是一个好主意。如果条件变量未始终与单个互斥锁一起使用,则无法确保不会丢失信号。而且,如果您使用两个互斥锁并在发出信号时同时锁定这两个互斥锁,则可能会出现死锁。互斥锁确保仅在监听信号的线程处于pthread_cond_wait() 调用中或未持有互斥锁(并且可能不关心当时的条件)时才发送信号。
  • 没有什么能阻止您使用不同的互斥锁,但如果您这样做,程序将无法(可靠地)工作。使用相同的互斥锁可以使信号和等待保持同步。

标签: c pthreads mutex


【解决方案1】:

对于下面的代码,互斥量将在时间秒之前不可用 cond_broadcast 被执行(假设多个线程已经在等待 条件)。

我认为您的意思是,在第二次调用该函数时,调用 pthread_cond_broadcast() 的线程将无法使用互斥锁,但这无关紧要。调用pthread_cond_broadcast() 与持有任何互斥锁无关。

或者您的意思是,在第二次广播发生时,先前被阻塞的线程之一将获得互斥锁,但是(1)不确定,(2)如果确实发生了,则与尊重广播。

在这种情况下,广播是否选择 线程(等待条件)将互斥锁交给并等待 由其他线程或第二个 cond_broadcast 解锁的互斥锁 被忽略了?

两者都没有。 pthread_cond_broadcast()pthread_cond_signal() 在锁定或转移任何互斥锁的控制权方面没有任何作用。他们只是唤醒相关 CV 上阻塞的线程。每个这样的线程必须在从调用返回之前获取互斥锁是一个单独的考虑因素——它们都正常竞争以锁定互斥锁,并且在他们这样做之前不会从pthread_cond_wait() 返回。他们也不会回到等待状态,除非先从等待中返回,然后再次调用pthread_cond_wait()

但这并不意味着您的代码中的第二个pthread_cond_broadcast() 必然无效。刚刚唤醒的线程之一可能会在两次调用之间循环并再次等待 CV,或者其他一些线程可能会到达 CV。只要第一个线程释放互斥锁,这就会成为可能,并且线程尝试做的第一件事是另一个广播这一事实并不能确保广播在另一个线程开始等待之前发生。

您不太可能希望像这样一个接一个地进行两个广播,但是您保留哪一个对程序的整体语义几乎没有影响(如果有的话)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-03-27
    • 1970-01-01
    • 2019-08-08
    • 1970-01-01
    • 1970-01-01
    • 2016-12-14
    • 2023-03-03
    • 2021-06-18
    相关资源
    最近更新 更多