假设我有4个线程,一个生产者和三个消费者,一个互斥量和一个条件变量,每个消费者都运行相同的函数,如下所示:
mutexlock(mutex)
signal[i] = 1;
while(signal[i] == 1) {
condwait(cond, mutex)
}
mutexunlock(mutex)制作人做了下面的事情
if(signal == 1)
{
set 0 - atomically using CAS
mutexlock(mutex)
condbroadcast(cond)
mutexunlock(mutex)
}比方说,如果锁中有多个消费者,他们不会争抢cond变量吗?我是否应该为每个线程创建一个条件变量,或者p_thread条件变量是否可以在没有任何争用条件的情况下跨多个线程共享?
发布于 2017-06-06 14:55:53
当你创建一个多线程程序时,它们共享资源信号,所有的三个线程都将竞争resources.When信号== 0,当你发送广播时,没有获得资源的线程会被放入条件variable.And的队列中,条件变量中所有等待的线程都会变弱,竞争resouce.Here是C语言中多线程初学者的tourial。
发布于 2017-06-08 17:48:03
pthread_cond_wait的语义是释放获得性互斥并阻塞条件变量。当信号到达时,块被释放,然后pthread_cond_wait获得互斥锁。
因此,在您的例子中,当您使用pthread_cond_broadcast时,所有阻塞在条件上的线程都将超过这个点,但在此之后,其中一个线程将被授予互斥锁。哪个?这取决于解锁后调度器唤醒它们的顺序,以及在两个或更多线程试图在某个时刻获取锁的情况下的pthread实现。可以放心地认为它是随机的。
如果您用pthread_cond_signal替换pthread_cond_broadcast,信号将被传递到一些线程。是的,它应该是一个,但有时可以从条件变量中释放多个。不过,发送信号的线程(或多个线程)将由调度程序选择。如果不止一个从cond等待中被唤醒,它们将争夺互斥量。和以前一样,你可以认为结果是随机的。
让我们来看看documentation
如果多个线程在条件变量上被阻塞,则调度策略应确定线程解锁的顺序。
在多处理器上,pthread_cond_signal()的实现可能无法避免对一个条件变量上阻塞的多个线程进行解锁。
顺便说一句,我很好奇。最近有几个关于条件变量的问题(你们都在为你的uni做一个项目吗?)在过去24小时内我看到的每个问题中,我都看到了下面的信号模式:
pthread_mutex_lock(&mutex);
pthread_cond_broadcast(&cond); /* or signal */
pthread_mutex_unlock(&mutex);当等待线程具有以下条件时:
pthread_mutex_lock(&mutex);
pthread_cond_wait(&cond,&mutex);
/* do something */
pthread_mutex_unlock(&mutex);这背后的原因是什么?
等待线程在cond上等待,mutex被释放。所以发信号的线程获取mutex上的锁,发信号给其他线程。就在这一刻,他们--仍然在pthread_cond_wait内部--通过了cond封锁,然后他们试图获得mutex上的锁。当然,它们不能,因为锁是由信令线程持有的。然后,信令线程释放mutex,等待线程最终可以通过一个接一个地获取mutex来进行处理。
对于信号写入者和等待的消费者来说,这个模式应该如下所示。
对于编写者:
while(loop_condition) {
prepare_data() /* it could be a long process */
lock(&mutex);
add_data_to_queue(); /* fast, inside critical section */
unlock(&mutex);
signal(&cond); /* or broadcast */
}对于消费者:
while(consumer_loop_condition) {
lock(&mutex);
while(!data_ready_to_process()) {
wait(&cond,&mutex);
}
fetch_data(); /* fast, still inside critical section */
unlock(&mutex);
if(got_data) {
process_data(); /* could be a long process */
}
}有关cond/mutexes的更多解释和一些示例代码,请参阅this answer。
https://stackoverflow.com/questions/44381035
复制相似问题