gpt4 book ai didi

c++ - pthread_cond_timedwait() & pthread_cond_broadcast() 解释

转载 作者:太空狗 更新时间:2023-10-29 21:22:07 28 4
gpt4 key购买 nike

所以我搜索了关于堆栈溢出和其他资源的高低,但我无法理解与上述功能有关的一些事情。具体来说,

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

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

最佳答案

(1) pthread_cond_timedwait()

简短(浅显)的解释它是如何工作的。

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

2) 当您的程序将其控制转移到该函数时,该函数原子地释放关联的互斥量,让其他线程有机会获得它。当您等待时,互斥锁被解锁。解锁它是功能责任。如果函数实现无法做到这一点,则只有一个线程会处理关联的互斥体。

3) 当函数返回时,无论是由于超时还是由于接收到信号,函数都会原子地锁定互斥体。锁定互斥量是函数的职责。

4) 现在您应该再次解锁互斥量。

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

(2) pthread_cond_broadcast()

用 pthread_cond_broadcast() 发出信号会导致所有等待的线程唤醒并开始一个接一个地处理。使用 pthread_cond_signal() 发出信号只会唤醒一个线程。要“感受”这个概念,您可以使用以下代码来说明这个想法。将 pthread_cons_signal 替换为 pthread_cond_brodcast。考虑到当使用 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;
}

关于c++ - pthread_cond_timedwait() & pthread_cond_broadcast() 解释,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21299957/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com