pthread_cond_在一个pthread_互斥锁解锁前后广播

pthread_cond_在一个pthread_互斥锁解锁前后广播,c,pthreads,mutex,C,Pthreads,Mutex,对于下面的代码,在执行second cond_broadcast(第二个cond_广播)时,如果多个线程已经在等待该条件,互斥锁将不可用。在这种情况下,广播是否选择了等待条件将互斥对象交给的线程,并等待互斥对象被其他线程解锁,还是忽略了第二个cond_广播 void* func(void* arg){ pthread_mutex_lock(&m); while(condition){ pthread_cond_wait(&c,&m); } pthread_cond_bro

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

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);
}
对于下面的代码,互斥锁在第二时间将不可用 假设多个线程已在等待,则执行cond_广播 在这个条件下

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

或者,您的意思是,在第二次广播发生时,先前被阻止的线程之一将已获取互斥,但1不确定,2如果确实发生,则对广播没有特殊意义

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

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_广播和pthread_cond_信号在锁定或传输任何互斥锁的控制中不起作用。它们只是唤醒关联CV上阻塞的线程。每个这样的线程在从调用返回之前都必须获取互斥锁,这是一个单独的考虑因素——它们都会正常地争用以锁定互斥锁,并且不会从pthread_cond_返回,直到它们返回为止。它们也不会返回等待,除非先从等待返回,然后再次调用pthread_cond_wait

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


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

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