C++多线程条件变量和虚假唤醒
条件变量:
条件变量是利用线程间共享的全局变量(关键段、读写锁)进行同步的一种机制。为了防止其他线程竞争,条件变量的使用总是和一个互斥锁结合在一起。
它主要实现两个动作:1)线程等待某个条件,条件为真则继续执行,条件为假则将自己挂起(为了避免忙等待,节省CPU资源);
2)线程执行某些处理后,条件成立,则会通知该等待线程继续执行。
功能函数
BOOL SleepConditionVariableCS(
PCONDITION_VARIABLE ConditionVariable,
PCRITICAL_SECTION CriticalSection,
DWORD dwMilliseconds
);
在指定的条件变量上休眠并将指定的临界区作为原子操作释放。
返回值:0表示成功代表被其他线程正常唤醒,其他是失败,比如错误码ERROR_TIMEOUT表示在被其他线程唤醒前超时。
函数在使用前一般配合区域互斥锁先上锁。
唤醒函数:
WakeConditionVariable WakeAllConditionVariable 分别是单个唤醒和所有唤醒,被唤醒后线程会重新进入之前休眠时释放的CriticalSection
对应Linux等待函数:pthread_cond_wait
对应Linux唤醒函数:pthread_cond_signal(至少唤醒1个)以及pthread_cond_broadcast(唤醒所有等待该条件的线程)
虚假唤醒:spurious wakeup
当多个线程同时在等待同一条件,此时条件满足发起唤醒则可能会唤醒多个线程,但是如果对应的资源不够所有唤醒线程使用,
则剩余线程的唤醒就是无意义的,也就被称作虚假唤醒。
避免虚假唤醒:
在睡眠返回之后重新检查条件判断(while代替if)。
比如线程执行代码块如下:
while(true)
{
pthread_mutex_lock(&mutex);
while (workQueue == nullptr) // 这里如果if的话,虚假唤醒时则会去获取空指针的内容,导致出错。
{
pthread_cond_wait(&cond, &mutex);
}
messagePtr = workQueue;
workQueue = workQueue->next;
pthread_mutex_unlock(&mutex);
}
版权归原作者 UBU1994 所有, 如有侵权,请联系我们删除。