Proměnné podmínky
Proměnné podmínky jsou primitivy synchronizace, které umožňují podprocesům čekat, dokud nedojde k určité podmínce. Proměnné podmínky jsou objekty uživatelského režimu, které nelze sdílet napříč procesy.
Proměnné podmínky umožňují vláknům atomicky uvolnit zámek a vstoupit do stavu spánku. Dají se použít s kritickými oddíly nebo zámky čtečky/zapisovače (SRW). Proměnné podmínky podporují operace, které "wake one" nebo "wake all" čekající vlákna. Po probuzení vlákna znovu získá zámek, který se uvolní, když vlákno vstoupilo do stavu spánku.
Všimněte si, že volající musí přidělit CONDITION_VARIABLE strukturu a inicializovat ji buď voláním InitializeConditionVariable (k dynamické inicializaci struktury) nebo přiřadit konstantní CONDITION_VARIABLE_INIT proměnné struktury (pro inicializaci struktury staticky).
Windows Server 2003 a Windows XP: proměnné podmínky nejsou podporovány.
Následují funkce proměnných podmínky.
Funkce proměnné podmínky | Popis |
---|---|
InitializeConditionVariable | Inicializuje proměnnou podmínky. |
SleepConditionVariableCS | Přepne na zadanou proměnnou podmínky a uvolní zadanou kritickou část jako atomické operace. |
SleepConditionVariableSRW | Přepne na zadanou proměnnou podmínky a uvolní zadaný zámek SRW jako atomické operace. |
WakeAllConditionVariable | Probouzí všechna vlákna čekající na zadanou proměnnou podmínky. |
WakeConditionVariable | Probudí jedno vlákno čekající na zadanou proměnnou podmínky. |
Následující pseudokód ukazuje typický vzor použití proměnných podmínky.
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
}
Například při implementaci zámku čtečky/zapisovače by funkce TestPredicate
ověřila, že aktuální požadavek na zámek je kompatibilní se stávajícími vlastníky. Pokud ano, získejte zámek; jinak, spí. Podrobnější příklad najdete v tématu Použití proměnných podmínky.
Proměnné podmínky podléhají nepravdivým buzením (těm, které nejsou spojeny s explicitním probuzením) a odcizenými probuzeními (jiné vlákno se spravuje spustit před vláknem woken). Proto byste měli znovu zkontrolovat predikát (obvykle v , zatímco smyčka) po návratu operace spánku.
Další vlákna můžete probudit pomocí WakeConditionVariable nebo WakeAllConditionVariable uvnitř nebo mimo zámek přidružený k proměnné podmínky. Zámek je obvykle lepší uvolnit před probuzením jiných vláken, aby se snížil počet kontextových přepínačů.
Často je vhodné použít více než jednu proměnnou podmínky se stejným zámkem. Například implementace zámku čtečky/zapisovače může použít jednu kritickou část, ale samostatné proměnné podmínky pro čtenáře a zapisovače.
Související témata