gpt4 book ai didi

events - 基于 pthread 的事件仅唤醒等待线程

转载 作者:行者123 更新时间:2023-12-04 20:25:55 71 4
gpt4 key购买 nike

在我的 C++ 程序中,我有一个 CEvent 类,它带有基于 pthreads(在 Linux 上运行)的触发器和等待成员函数。如果有一个等待过程,实现是很明显的(即网上有很多例子)。但是现在我需要满足多个线程正在等待事件并且在调用 trigger() 时都应该可靠地唤醒的要求。作为第二个条件,只有在调用 trigger() 时正在等待的线程才能唤醒。

我目前的代码:

void CEvent::trigger() {
pthread_mutex_lock(&mutex);
wakeUp = true;
pthread_cond_broadcast(&condition)
pthread_mutex_unlock(&mutex);
wakeUp = false;
}

void CEvent::wait() {
pthread_mutex_lock(&mutex);
while (!wakeUp)
pthread_cond_wait(&condition, &mutex)

pthread_mutex_unlock(&mutex);
}

这似乎几乎可以工作,因为在我将wakeUp 设置回false 之前等待唤醒的所有线程。然而,在广播和唤醒唤醒之间,调用 wait() 的其他(或相同)线程也将立即唤醒,这是 Not Acceptable 。在 mutext 解锁之前放置 wakeUp = false 可防止线程唤醒。

我的问题:
* pthread_cond_broadcast 什么时候返回? IE。有没有保证它只会在所有线程都唤醒后才返回,还是可以在之前返回?
* 是否有针对此问题的推荐解决方案?

最佳答案

请忽略我之前的虚假回答。触发线程解锁互斥锁(从而释放等待线程)与设置唤醒值之间存在竞争。这意味着另一个(不等待)线程可以进来,获取互斥锁,并在 wakeUp 中看到真值。无需等待即可退出。另一个错误是等待的线程会在 wakeUp 之后唤醒。被重置并立即恢复等待。

解决此问题的一种方法是使用计数 - 每个正在等待的线程都会增加计数,然后触发器将等待直到许多线程在恢复之前唤醒。然后,您必须确保在这发生之前不允许非等待线程开始等待。

// wake up "waiters" count of waiting threads
void CEvent::trigger()
{
pthread_mutex_lock(&mutex);

// wakey wakey
wakeUp = true;
pthread_cond_broadcast(&condition);

// wait for them to awake
while (waiters>0)
pthread_cond_wait(&condition, &mutex);

// stop waking threads up
wakeUp = false;

// let any "other" threads which were ready to start waiting, do so
pthread_cond_broadcast(&condition);
pthread_mutex_unlock(&mutex);
}

// wait for the condition to be notified for us
void CEvent::wait()
{
pthread_mutex_lock(&mutex);

// wait for us to be allowed to start waiting
// we have to wait until any currrently being woken threads have gone
while (wakeUp)
pthread_cond_wait(&condition, &mutex);

// our turn to start waiting
waiters ++;

// waiting
while (!wakeUp)
pthread_cond_wait(&condition, &mutex);

// finished waiting, we were triggered
waiters --;

// let the trigger thread know we're done
pthread_cond_broadcast(&condition);
pthread_mutex_unlock(&mutex);
}

关于events - 基于 pthread 的事件仅唤醒等待线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/919860/

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