条件变量
条件变量是同步基元,使线程能够等待特定条件出现。 条件变量是不能跨进程共享的用户模式对象。
条件变量使线程能够原子释放锁并进入睡眠状态。 它们可与关键节或精简的读取器/编写器(SRW)锁一起使用。 条件变量支持“唤醒一个”或“唤醒所有”等待线程的作。 线程唤醒后,它会在线程进入睡眠状态时重新获取释放的锁。
请注意,调用方必须分配 CONDITION_VARIABLE 结构,并通过调用 InitializeConditionVariable(动态初始化结构)或将常量 CONDITION_VARIABLE_INIT 分配给结构变量(以静态方式初始化结构)来初始化它。
Windows Server 2003 和 Windows XP:不支持 条件变量。
以下是条件变量函数。
条件变量函数 | 描述 |
---|---|
InitializeConditionVariable | 初始化条件变量。 |
SleepConditionVariableCS | 在指定的条件变量上睡眠,并将指定的关键节作为原子作释放。 |
SleepConditionVariableSRW | 在指定的条件变量上休眠,并将指定的 SRW 锁作为原子作释放。 |
WakeAllConditionVariable | 唤醒所有等待指定条件变量的线程。 |
WakeConditionVariable | 唤醒等待指定条件变量的单个线程。 |
以下伪代码演示条件变量的典型使用模式。
CRITICAL_SECTION CritSection;
CONDITION_VARIABLE ConditionVar;
void PerformOperationOnSharedData()
{
EnterCriticalSection(&CritSection);
// Wait until the predicate is TRUE
while( TestPredicate() == FALSE )
{
SleepConditionVariableCS(&ConditionVar, &CritSection, INFINITE);
}
// The data can be changed safely because we own the critical
// section and the predicate is TRUE
ChangeSharedData();
LeaveCriticalSection(&CritSection);
// If necessary, signal the condition variable by calling
// WakeConditionVariable or WakeAllConditionVariable so other
// threads can wake
}
例如,在读取器/编写器锁的实现中,TestPredicate
函数将验证当前锁请求是否与现有所有者兼容。 如果是,请获取锁;否则,请睡觉。 有关更详细的示例,请参阅 使用条件变量。
条件变量受到虚假唤醒(与显式唤醒无关的唤醒)和被盗唤醒(另一个线程设法在唤醒线程之前运行)。 因此,在睡眠作返回后,应重新检查谓词(通常位于 循环中)。
可以使用 WakeConditionVariable 或 WakeAllConditionVariable 与条件变量关联的锁内外唤醒其他线程。 在唤醒其他线程之前,最好释放锁以减少上下文切换的数量。
使用同一锁的多个条件变量通常很方便。 例如,读取器/编写器锁的实现可能使用单个关键部分,但针对读取器和编写器使用不同的条件变量。
相关主题