条件变量
条件变量是同步基元,使线程能够等待特定条件发生。 条件变量是用户模式对象,不能跨进程共享。
条件变量使线程能够以原子方式释放锁并进入休眠状态。 它们可与关键部分或超薄读取器/编写器 (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
函数将验证当前锁请求是否与现有所有者兼容。 如果是,请获取锁;否则为睡眠。 有关更详细的示例,请参阅 使用条件变量。
条件变量受到虚假唤醒的影响, (那些与显式唤醒) 无关的唤醒变量, (另一个线程设法在唤醒线程) 之前运行而被盗的唤醒。 因此,应在睡眠操作返回后,在 while 循环) 中重新检查谓词 (。
可以在与条件变量关联的锁内部或外部使用 WakeConditionVariable 或 WakeAllConditionVariable 唤醒其他线程。 通常最好在唤醒其他线程之前释放锁,以减少上下文切换的数量。
使用同一锁的多个条件变量通常很方便。 例如,读取器/编写器锁的实现可能使用单个关键部分,但对读取器和编写器使用单独的条件变量。