Kritikus szakaszobjektumok
A kritikus szakaszobjektumok a mutex objektum által biztosítotthoz hasonló szinkronizálást biztosítanak, azzal a kivétellel, hogy egy kritikus szakaszt csak egyetlen folyamat szálai használhatnak. A kritikus szakaszobjektumok nem oszthatók meg a folyamatok között.
Az esemény-, mutex- és szemaphore-objektumok egy folyamatalapú alkalmazásban is használhatók, de a kritikus szakaszobjektumok valamivel gyorsabb és hatékonyabb mechanizmust biztosítanak a kölcsönös kizárás szinkronizálásához (processzorspecifikus teszt és utasításkészlet). A mutex-objektumokhoz hasonlóan a kritikus fontosságú szakaszobjektumok egyszerre csak egy szál tulajdonában lehetnek, ami hasznossá teszi a megosztott erőforrások egyidejű hozzáféréssel szembeni védelmét. A mutex objektumokkal ellentétben nem lehet megállapítani, hogy egy kritikus szakaszt elhagytak-e.
A Windows Server 2003 service Pack 1 (SP1) csomaggal kezdődően a kritikus szakaszon várakozó szálak nem kapják meg a kritikus szakaszt első alkalommal, első alkalommal. Ez a változás jelentősen növeli a legtöbb kód teljesítményét. Egyes alkalmazások azonban az első, első előtti (FIFO) sorrendtől függenek, és a Windows jelenlegi verzióiban (például a kritikus szakaszokat sebességkorlátozóként használó alkalmazásoknál) rosszul vagy egyáltalán nem teljesíthetnek. Annak érdekében, hogy a kód továbbra is megfelelően működjön, előfordulhat, hogy további szinkronizálási szintet kell hozzáadnia. Tegyük fel például, hogy van egy gyártói szála és egy fogyasztói szála, amely kritikus szakaszobjektumot használ a munkájuk szinkronizálásához. Hozzon létre két eseményobjektumot, egyet az egyes szálakhoz, amelyek jelzik, hogy készen áll a másik szál folytatására. A fogyasztói szál megvárja, amíg a gyártó jelezi az eseményt, mielőtt belép a kritikus szakaszba, és a gyártói szál megvárja, amíg a fogyasztói szál jelzi az eseményt, mielőtt belép a kritikus szakaszba. Miután minden szál elhagyta a kritikus szakaszt, jelzi az eseményt, hogy engedje fel a másik szálat.
Windows Server 2003 és Windows XP: kritikus szakaszon várakozó szálakat a rendszer hozzáadja a várakozási sorhoz; a rendszer felébreszti őket, és általában abban a sorrendben szerzi be a kritikus szakaszt, amelyben hozzá lettek adva az üzenetsorhoz. Ha azonban a szálak elég gyorsan hozzá vannak adva ehhez az üzenetsorhoz, a teljesítmény csökkenhet az egyes várakozási szálak felébresztéséhez szükséges idő miatt.
A folyamat felelős a kritikus szakasz által használt memória kiosztásáért. Ez általában egy CRITICAL_SECTIONtípusú változó egyszerű deklarálásával történik. Mielőtt a folyamat szálai használnák, inicializálja a kritikus szakaszt az InitializeCriticalSection vagy InitializeCriticalSectionAndSpinCount függvénnyel.
A szál az EnterCriticalSection vagy TryEnterCriticalSection függvényt használja egy kritikus szakasz tulajdonjogának lekéréséhez. A LeaveCriticalSection függvényt használja egy kritikus szakasz tulajdonjogának felszabadításához. Ha a kritikus szakasz objektuma jelenleg egy másik szál tulajdonában van, EnterCriticalSection határozatlan ideig várakozik a tulajdonjogra. Ezzel szemben, ha egy mutex objektumot használnak a kölcsönös kizáráshoz, a várakozási függvények elfogadni egy megadott időtúllépési időközt. A TryEnterCriticalSection függvény a hívó szál blokkolása nélkül próbál meg egy kritikus szakaszt megadni.
Ha egy szál rendelkezik egy kritikus szakaszsal, további hívásokat kezdeményezhet az EnterCriticalSectionvagy TryEnterCriticalSection anélkül, hogy blokkolná a végrehajtást. Ez megakadályozza, hogy egy szál holtpontra ássa magát, miközben a már birtokolt kritikus szakaszra vár. A tulajdonjog felszabadításához a szálnak egyszer kell meghívnia LeaveCriticalSection minden alkalommal, amikor a kritikus szakaszba lépett. Nincs garancia arra, hogy a várakozási szálak milyen sorrendben szerezik meg a kritikus szakasz tulajdonjogát.
A szál a InitializeCriticalSectionAndSpinCount vagy SetCriticalSectionSpinCount függvényt használja a kritikus szakaszobjektum pörgetési számának megadásához. A fonás azt jelenti, hogy amikor egy szál megpróbál beszerezni egy zárolt kritikus szakaszt, a szál belép egy hurokba, ellenőrzi, hogy ki van-e adva a zárolás, és ha a zárolás nem szabadul fel, a szál alvó állapotba kerül. Az egyprocesszoros rendszerek esetében a pörgetések száma figyelmen kívül lesz hagyva, és a kritikus szakasz pörgetési száma 0 (nulla) értékre van állítva. Többprocesszoros rendszereken, ha a kritikus szakasz nem érhető el, a hívó szál dwSpinCount alkalommal pörög, mielőtt várakozási műveletet hajt végre a kritikus szakaszhoz társított szemaforon. Ha a kritikus szakasz szabaddá válik a pörgetési művelet során, a hívó szál elkerüli a várakozási műveletet.
A folyamat bármely szála használhatja a DeleteCriticalSection függvényt a kritikus szakaszobjektum inicializálásakor lefoglalt rendszererőforrások felszabadításához. A függvény meghívása után a kritikus szakaszobjektum nem használható szinkronizáláshoz.
Ha egy kritikus szakaszobjektum tulajdonosa, csak azokat a szálakat érinti, amelyek tulajdonjogra várnak az EnterCriticalSectionhívásában. A nem várakozó szálak továbbra is szabadon futnak.
Kapcsolódó témakörök