Events 基于pthread的事件仅唤醒等待的线程 在我的C++程序中,我有一个基于PultType(在Linux上运行)的触发器和等待成员函数类CCENT。如果有一个等待过程,那么实现是非常明显的(即许多在线示例)。但是,现在我需要满足多个线程正在等待事件的要求,并且在调用trigger()时应该可靠地唤醒所有线程。第二个条件是,只有在调用trigger()时等待的线程才会被唤醒
我当前的代码:Events 基于pthread的事件仅唤醒等待的线程 在我的C++程序中,我有一个基于PultType(在Linux上运行)的触发器和等待成员函数类CCENT。如果有一个等待过程,那么实现是非常明显的(即许多在线示例)。但是,现在我需要满足多个线程正在等待事件的要求,并且在调用trigger()时应该可靠地唤醒所有线程。第二个条件是,只有在调用trigger()时等待的线程才会被唤醒,events,pthreads,Events,Pthreads,我当前的代码: 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);
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);
}
这似乎几乎是可行的,因为在我将唤醒设置回false之前,所有等待唤醒的线程都会被唤醒。但是,在广播和重置唤醒之间,调用wait()的其他(或相同)线程也会立即唤醒,这是不可接受的。在mutext解锁之前放置wakeUp=false可防止线程唤醒
我的问题是:
*pthread_cond_广播何时返回?也就是说,有没有保证它只会在所有线程都唤醒后返回,或者可以在所有线程唤醒前返回?
*这个问题有什么建议的解决方案吗?请忽略我以前的假答案。触发器线程解锁互斥锁(从而释放等待的线程)然后设置唤醒值的时间之间存在竞争。这意味着另一个(不等待)线程可以进入,获取互斥锁,并在
唤醒中看到真实值,然后不等待退出。另一个错误是,一个正在等待的线程将在唤醒
重置后唤醒,并立即恢复等待
解决这个问题的一种方法是使用count-每个正在等待的线程都将增加计数,然后触发器将等待,直到有那么多线程醒来后再继续。然后,您必须确保不允许非等待线程开始等待,直到发生这种情况
// 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);
}