【发布时间】: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()调用中或未持有互斥锁(并且可能不关心当时的条件)时才发送信号。 -
没有什么能阻止您使用不同的互斥锁,但如果您这样做,程序将无法(可靠地)工作。使用相同的互斥锁可以使信号和等待保持同步。