简体   繁体   English

pthread_cond_timedwait()&pthread_cond_broadcast()解释

[英]pthread_cond_timedwait() & pthread_cond_broadcast() explained

So I have searched high and low on stack overflow and other resources but I am unable to understand a few things with regards to the aforementioned functions. 所以我已经搜索了堆栈溢出和其他资源的高低,但我无法理解有关上述功能的一些事情。 Specifically, 特别,

1)When pthread_cond_timedwait() returns because a timer value has run out, how does it automatically re-acquire the mutex. 1)当pthread_cond_timedwait()因计时器值用完而返回时,它如何自动重新获取互斥锁。 The mutex could potentially be locked elsewhere. 互斥锁可能会被锁定在别处。 For instance, in say a producer-consumer queue, the consumer could be waiting using the timedwait() variant. 例如,在生产者 - 消费者队列中,消费者可能正在使用timedwait()变体进行等待。 From explanations I have read, it appears that the mutex will automatically be re-acquired when the thread wakes up. 从我读过的解释来看,当线程唤醒时,似乎会自动重新获取互斥锁。 This baffles me? 这让我感到困惑? Or is it that it will wake up after the timer runs out and then check the predicate and lock again. 或者是它会在计时器用完后唤醒,然后检查谓词并再次锁定。 That makes no sense? 这是没有意义的?

2)When a bunch of threads have acquired a mutex and are now all waiting on a simple pthread_cond_wait(), what will happen if another thread issues a pthread_cond_broadcast(). 2)当一堆线程获得了一个互斥体并且现在都在等待一个简单的pthread_cond_wait()时,如果另一个线程发出pthread_cond_broadcast()会发生什么。 Will each of the threads (as determined by the scheduler) wake up one by one, acquire the mutex in sequence and then each of them proceed? 将每个线程(由调度程序确定)逐个唤醒,按顺序获取互斥锁,然后每个线程都继续执行? Or will only one thread of the entire list of threads wake up. 或者只会唤醒整个线程列表中的一个线程。 I would assume that the latter of the two behaviors would be possible using pthread_cond_signal() as well. 我假设使用pthread_cond_signal()也可以使用后两种行为。 Also, if the previous approach is the right behavior, then we can assume that some other thread might end up calling wait() on the variable somewhere else. 此外,如果前面的方法是正确的行为,那么我们可以假设其他一些线程可能最终在其他地方调用变量wait()。 Would that then put all these other waiting threads back into a blocked state and waiting for a signal. 那么那会将所有这些其他等待线程重新置于阻塞状态并等待信号。 Or would each of them continue to wake up and make progress one by one? 或者他们每个人都会继续醒来,一个接一个地取得进步?

(1) pthread_cond_timedwait() (1) pthread_cond_timedwait()

A short (and shallow) explanation how it works. 简短(浅浅)解释它是如何工作的。

1) The mutex, associated with the pthread_cond_timewait() should be locked before a call to the function. 1)在调用函数之前,应锁定与pthread_cond_timewait()关联的互斥锁。 It is your responsibility to do it. 这是你的责任。 Otherwise, the function behavior is undefined. 否则,函数行为是未定义的。

2) When your program transfers its control to the function, the function ATOMICALLY releases the associated mutex, giving other threads a chance to acquire it. 2)当您的程序将其控件转移到该函数时,函数ATOMICALLY释放相关的互斥锁,使其他线程有机会获取它。 When you are waiting, the mutex is unlocked. 等待时,互斥锁将解锁。 It is the function responsibility to unlock it. 解锁它是功能的责任。 If the function implementation could not do it, only one single thread would deal with the associated mutex. 如果函数实现无法执行,则只有一个线程处理相关的互斥锁。

3) When the function returns, either as a result of timeout or as a result of receiving a signal, the function ATOMICALLY locks the mutex back. 3)当函数返回时,无论是由于超时还是由于接收到信号,函数ATOMICALLY都会锁定互斥锁。 It is the function responsibility to lock the mutex. 锁定互斥锁是功能。

4) Now the mutex should be unlocked again by you. 4)现在应该再次解锁互斥锁。

The word "atomically" in the explanation means, that the function itself is thread safe. 解释中的“原子”一词意味着函数本身是线程安全的。

(2) pthread_cond_broadcast() (2) pthread_cond_broadcast()

Signaling with pthread_cond_broadcast() causes to all waiting threads to wake up and start processing one by one. 使用pthread_cond_broadcast()进行信号传递会导致所有等待的线程被唤醒并逐个开始处理。 Signaling with pthread_cond_signal() causes only one single thread to wake up. 使用pthread_cond_signal()发送信号只会唤醒一个线程。 To "feel" the concept you may play with the following code that illustrates the idea. 要“感觉”这个概念,您可以使用以下代码来说明这个想法。 Replace the pthread_cons_signal with the pthread_cond_brodcast. 用pthread_cond_brodcast替换pthread_cons_signal。 Take into consideration that the program will never terminate when pthread_cons_signal is used: only one waiter thread gets the signal and escapes from the wait loop. 考虑到当使用pthread_cons_signal时程序永远不会终止:只有一个服务员线程获取信号并从等待循环中逃脱。

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
int value = 0;

void* waiter(void* arg)
{
  int* tid = (int*)arg;

  printf("waiter started %d\n", *tid);

  pthread_mutex_lock(&mutex);
  while(value == 0)
  {
    pthread_cond_wait(&cond, &mutex);
  }
  sleep(10);
  printf("waiter %d releases\n", *tid);
  pthread_mutex_unlock(&mutex);

}

void* notifier(void* arg)
{
  sleep(2);
  pthread_mutex_lock(&mutex);
  value = 1;
  //pthread_cond_broadcast(&cond);
  pthread_cond_signal(&cond);
  pthread_mutex_unlock(&mutex);
}

int main(void)
{
  pthread_t w1; // waiter
  int tid1=1;
  pthread_t w2; // waiter
  int tid2=2;
  pthread_t n1; // notifier

  pthread_create(&w1, NULL, waiter, &tid1);
  pthread_create(&w2, NULL, waiter, &tid2);
  pthread_create(&n1, NULL, notifier, NULL);

  pthread_join(w1, NULL);
  pthread_join(w2, NULL);
  pthread_join(n1, NULL);
  return 0;
}  

If pthread_cond_timedwait() returns due to the timeout expiring, it will reacquire the mutex before returning. 如果pthread_cond_timedwait()由于超时到期而返回,它将在返回之前重新获取互斥锁。 This might mean that it has to wait for the mutex to be unlocked, if it is locked by another thread at that time. 这可能意味着它必须等待互斥锁解锁,如果它在那时被另一个线程锁定。 Essentially, it behaves as if it calls pthread_mutex_lock() before returning. 从本质上讲,它的行为就像在返回之前调用pthread_mutex_lock()一样。

When pthread_cond_broadcast() is called, all of the waiting threads will be woken, which means that they will all try to acquire the mutex and return. 当调用pthread_cond_broadcast() ,所有等待的线程都将被唤醒,这意味着它们都将尝试获取互斥锁并返回。 The mutex will serialise this, of course, so they will only return one-at-a-time. 当然,互斥锁会对此进行序列化,因此它们只能一次返回一次。 It doesn't matter what happens after this point - those threads will all eventually return from their pthread_cond_wait() call as soon as they can acquire the mutex. 在这一点之后发生了什么并不重要 - 这些线程一旦获得互斥锁就会最终从他们的pthread_cond_wait()调用返回。 Another thread calling pthread_cond_wait() does not affect this. 调用pthread_cond_wait()另一个线程不会影响这个。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM