Sdílet prostřednictvím


Objekty kritického oddílu

Objekt kritického oddílu poskytuje synchronizaci podobnou té, kterou poskytuje objekt mutex, s tím rozdílem, že kritický oddíl může používat pouze vlákna jednoho procesu. Objekty kritického oddílu nelze sdílet napříč procesy.

Objekty event, mutex a semaphore lze použít také v jednoprocesové aplikaci, ale kritické objekty oddílů poskytují mírně rychlejší, efektivnější mechanismus synchronizace vzájemného vyloučení (test specifický pro procesor a nastavení instrukce). Podobně jako objekt mutex může být kritický objekt oddílu vlastněn pouze jedním vláknem najednou, což je užitečné pro ochranu sdíleného prostředku před souběžným přístupem. Na rozdíl od objektu mutex neexistuje způsob, jak zjistit, jestli byl kritický oddíl opuštěn.

Počínaje systémem Windows Server 2003 s aktualizací Service Pack 1 (SP1) vlákna čekající na kritickou část nezískala kritickou část při prvním použití. Tato změna výrazně zvyšuje výkon většiny kódu. Některé aplikace ale závisejí na řazení fiFO (first-in) a můžou vůbec fungovat špatně nebo ne na aktuálních verzích Windows (například aplikace, které jako omezovač rychlosti používaly kritické části). Abyste měli jistotu, že váš kód bude dál fungovat správně, budete možná muset přidat další úroveň synchronizace. Předpokládejme například, že máte vlákno producenta a vlákno příjemce, které k synchronizaci jejich práce používá kritický objekt oddílu. Vytvořte dva objekty událostí, jeden pro každé vlákno, aby bylo možné signalizovat, že je připravené pro další vlákno pokračovat. Vlákno příjemce bude čekat, až producent před vstupem do kritického oddílu signalizuje událost a vlákno producenta bude čekat, až vlákno příjemce signalizuje událost před vstupem do kritické části. Jakmile každé vlákno opustí kritický oddíl, signalizuje událost, aby uvolnilo druhé vlákno.

Windows Server 2003 a Windows XP: do fronty čekání se přidají vlákna čekajících na kritický oddíl; jsou probuzeny a obecně získávají kritickou část v pořadí, v jakém byly přidány do fronty. Pokud jsou však vlákna přidána do této fronty dostatečně rychle, může být výkon degradován kvůli době, která trvá probudit každé čekající vlákno.

Proces je zodpovědný za přidělení paměti používané kritickým oddílem. Obvykle se to provádí jednoduše deklarací proměnné typu CRITICAL_SECTION. Před použitím vláken procesu inicializovat kritickou část pomocí InitializeCriticalSection nebo InitializeCriticalSectionAndSpinCount funkce.

Vlákno používá funkci EnterCriticalSection nebo TryEnterCriticalSection k vyžádání vlastnictví kritické části. Používá funkci LeaveCriticalSection k uvolnění vlastnictví kritické části. Pokud objekt kritického oddílu aktuálně vlastní jiné vlákno, EnterCriticalSection počká na vlastnictví neomezeně dlouho. Naproti tomu při použití objektu mutex pro vzájemné vyloučení čekací funkce přijmout zadaný interval časového limitu. Funkce TryEnterCriticalSection se pokusí zadat kritický oddíl bez blokování volajícího vlákna.

Pokud vlákno vlastní kritickou část, může provádět další volání EnterCriticalSection nebo TryEnterCriticalSection bez blokování jeho spuštění. Tím zabráníte zablokování vlákna při čekání na kritickou část, kterou už vlastní. Aby bylo možné uvolnit jeho vlastnictví, musí vlákno volat LeaveCriticalSection jednou pro každý vstup do kritické části. Neexistuje žádná záruka týkající se pořadí, ve kterém čekající vlákna získávají vlastnictví kritického oddílu.

Vlákno používá InitializeCriticalSectionAndSpinCount nebo SetCriticalSectionSectionSpin Count funkce k určení počtu čísel pro objekt kritického oddílu. Rotující znamená, že když se vlákno pokusí získat kritický oddíl, který je uzamčený, vlákno přejde do smyčky, zkontroluje, jestli je zámek uvolněn a pokud zámek není uvolněn, vlákno přejde do režimu spánku. V systémech s jedním procesorem se počet číselných čísel ignoruje a počet číselníku kritického oddílu je nastaven na 0 (nula). Pokud v multiprocesorových systémech není k dispozici kritická část, volající vlákno rotuje dwSpinCount krát před provedením operace čekání na semaphore, která je přidružena k kritické části. Pokud se kritický oddíl během operace otáčení uvolní, volající vlákno zabrání operaci čekání.

Jakékoli vlákno procesu může použít funkci DeleteCriticalSection k uvolnění systémových prostředků přidělených při inicializaci objektu kritického oddílu. Po zavolání této funkce nelze k synchronizaci použít objekt kritického oddílu.

Pokud je objekt kritického oddílu vlastněn, jedinými dalšími vlákny ovlivněnými jsou vlákna, která čekají na vlastnictví ve volání EnterCriticalSection. Vlákna, která nečekají, jsou volně spuštěná.

objekty Mutex

použití objektů kritického oddílu