Feltételváltozók
A feltételváltozók olyan szinkronizálási primitívek, amelyek lehetővé teszik, hogy a szálak megvárják, amíg egy adott feltétel bekövetkezik. A feltételváltozók olyan felhasználói módú objektumok, amelyek nem oszthatók meg a folyamatok között.
A feltételváltozók lehetővé teszik, hogy a szálak atomilag feloldják a zárat, és belépjenek az alvó állapotba. Ezek használhatók kritikus szakaszok vagy vékony olvasó/író (SRW) zárolások. A feltételváltozók támogatják azokat a műveleteket, amelyek "felébresztik" vagy "felébresztik az összeset" várakozó szálakat. Miután egy szál felébredt, újra megszerzi a feloldott zárolást, amikor a szál belépett az alvó állapotba.
Vegye figyelembe, hogy a hívónak ki kell osztania egy CONDITION_VARIABLE struktúrát, és inicializálnia kell az InitializeConditionVariable meghívásával (a struktúra dinamikus inicializálásához), vagy az állandó CONDITION_VARIABLE_INIT hozzá kell rendelnie a struktúraváltozóhoz (a szerkezet statikus inicializálásához).
Windows Server 2003 és Windows XP: feltételváltozók nem támogatottak.
A feltételváltozó függvényei a következők.
Feltételváltozó függvény | Leírás |
---|---|
InitializeConditionVariable | Inicializál egy feltételváltozót. |
SleepConditionVariableCS | A megadott feltételváltozón alszik, és a megadott kritikus szakaszt atomi műveletként bocsátja ki. |
SleepConditionVariableSRW | Alszik a megadott feltételváltozón, és felszabadítja a megadott SRW-zárolást atomi műveletként. |
WakeAllConditionVariable | Felébreszti a megadott feltételváltozóra várakozó összes szálat. |
WakeConditionVariable | Egyetlen szál felébresztése a megadott feltételváltozóra várva. |
Az alábbi pszeudokód a feltételváltozók tipikus használati mintáját mutatja be.
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
}
Az olvasó-író zárolás implementációjában például a TestPredicate
függvény ellenőrzi, hogy az aktuális zárolási kérés kompatibilis-e a meglévő tulajdonosokkal. Ha igen, szerezze be a zárolást; ellenkező esetben aludjon. Részletesebb példa: Feltételváltozók használata.
A feltételváltozók hamis ébresztéseknek vannak kitéve (amelyek nincsenek explicit ébresztéssel társítva) és ellopott ébresztések (egy másik szál a felébresztett szál előtt fut). Ezért újra ellenőriznie kell egy predikátumot (általában egy , miközben ciklusban) az alvó művelet visszatérése után.
Más szálakat is felébreszthet WakeConditionVariable vagy WakeAllConditionVariable a feltételváltozóhoz társított zároláson belül vagy kívül. Általában jobb feloldani a zárolást, mielőtt felébresztené a többi szálat a környezeti kapcsolók számának csökkentése érdekében.
Gyakran kényelmes több feltételváltozót is használni ugyanazzal a zárolással. Egy olvasó/író zárolásának implementálása például egyetlen kritikus szakaszt, de külön feltételváltozókat használhat az olvasók és írók számára.
Kapcsolódó témakörök