Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/155.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ pthread_cond_timedwait()&;pthread_cond_broadcast()已解释_C++_Multithreading_Pthreads_Posix - Fatal编程技术网

C++ pthread_cond_timedwait()&;pthread_cond_broadcast()已解释

C++ pthread_cond_timedwait()&;pthread_cond_broadcast()已解释,c++,multithreading,pthreads,posix,C++,Multithreading,Pthreads,Posix,因此,我在堆栈溢出和其他资源上进行了大量的搜索,但我无法理解与上述函数有关的一些事情。具体来说, 1) 当pthread_cond_timedwait()由于计时器值已用完而返回时,它如何自动重新获取互斥锁。互斥锁可能被锁定在其他地方。例如,在生产者-消费者队列中,消费者可以使用timedwait()变量等待。从我读到的解释来看,当线程唤醒时,互斥锁似乎会自动重新获取。这让我困惑吗?或者它将在计时器用完后唤醒,然后再次检查谓词并锁定。那没有意义 2) 当一组线程获得了互斥锁,并且现在都在等待一个

因此,我在堆栈溢出和其他资源上进行了大量的搜索,但我无法理解与上述函数有关的一些事情。具体来说,

1) 当pthread_cond_timedwait()由于计时器值已用完而返回时,它如何自动重新获取互斥锁。互斥锁可能被锁定在其他地方。例如,在生产者-消费者队列中,消费者可以使用timedwait()变量等待。从我读到的解释来看,当线程唤醒时,互斥锁似乎会自动重新获取。这让我困惑吗?或者它将在计时器用完后唤醒,然后再次检查谓词并锁定。那没有意义

2) 当一组线程获得了互斥锁,并且现在都在等待一个简单的pthread_cond_wait(),如果另一个线程发出pthread_cond_broadcast(),会发生什么情况。每个线程(由调度程序确定)是否会一个接一个地唤醒,按顺序获取互斥,然后继续执行?或者整个线程列表中只有一个线程被唤醒。我假设这两种行为中的后一种也可以使用pthread_cond_signal()实现。此外,如果前面的方法是正确的行为,那么我们可以假设其他线程可能会在其他地方调用变量wait()。这会使所有其他等待的线程回到阻塞状态并等待信号。或者他们会继续一个接一个地醒来并取得进展吗?

(1)pthread\u cond\u timedwait()

一个简短的(肤浅的)解释它是如何工作的

1) 在调用函数之前,应该锁定与pthread_cond_timewait()关联的互斥锁。这是你的责任。否则,函数行为未定义

2) 当您的程序将其控制转移到函数时,该函数会自动释放关联的互斥体,让其他线程有机会获得它。等待时,互斥锁将解锁。解锁是职能部门的责任。 如果函数实现不能做到这一点,那么只有一个线程将处理相关的互斥锁

3) 当函数返回时,无论是由于超时还是由于接收到信号,函数都会自动将互斥锁锁回。函数负责锁定互斥锁

4) 现在,互斥锁应该由您再次解锁

解释中的“原子”一词意味着函数本身是线程安全的

(2) pthread\u cond\u broadcast()

使用pthread_cond_broadcast()发送信号会使所有等待的线程唤醒并逐个开始处理。使用pthread_cond_signal()发送信号只会唤醒一个线程。为了“感受”这个概念,您可以使用下面的代码来演示这个想法。用pthread_cond_brodcast替换pthread_cons_信号。考虑到当使用pthread_cons_信号时,程序永远不会终止:只有一个服务员线程获得信号并从等待循环中逃逸

#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;
}  
#包括
#包括
#包括
#包括
pthread\u mutex\u t mutex=pthread\u mutex\u初始值设定项;
pthread_cond_t cond=pthread_cond_初始值设定项;
int值=0;
void*服务员(void*arg)
{
int*tid=(int*)arg;
printf(“服务员开始%d\n”,*tid);
pthread_mutex_lock(&mutex);
while(值==0)
{
pthread_cond_wait(&cond,&mutex);
}
睡眠(10);
printf(“服务员%d次发布”,*tid);
pthread_mutex_unlock(&mutex);
}
void*通知程序(void*arg)
{
睡眠(2);
pthread_mutex_lock(&mutex);
数值=1;
//pthread_cond_广播(&cond);
pthread_cond_信号(&cond);
pthread_mutex_unlock(&mutex);
}
内部主(空)
{
pthread_t w1;//服务员
int-tid1=1;
pthread_t w2;//服务员
int-tid2=2;
pthread_t n1;//通知程序
pthread_create(&w1,NULL,water,&tid1);
pthread_create(&w2,NULL,water,&tid2);
pthread_create(&n1,NULL,通知程序,NULL);
pthread_join(w1,NULL);
pthread_join(w2,NULL);
pthread_join(n1,NULL);
返回0;
}  

如果
pthread\u cond\u timedwait()
由于超时过期而返回,它将在返回前重新获取互斥锁。这可能意味着,如果互斥锁被另一个线程锁定,它必须等待互斥锁解锁。本质上,它的行为就像在返回之前调用
pthread\u mutex\u lock()

调用
pthread\u cond\u broadcast()
时,所有等待的线程都将被唤醒,这意味着它们都将尝试获取互斥锁并返回。互斥锁当然会将其序列化,因此它们每次只返回一次。在这一点之后发生什么都无关紧要——一旦获得互斥锁,这些线程最终都将从
pthread\u cond\u wait()
调用返回。另一个线程调用
pthread\u cond\u wait()
不会影响此操作