Sdílet prostřednictvím


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.

použití proměnných podmínky