One-Time inicializálás
Az összetevőket gyakran úgy tervezték, hogy inicializálási feladatokat hajtsanak végre, amikor először hívják őket, nem pedig betöltésre. Az egyszeri inicializálási függvények biztosítják, hogy ez az inicializálás csak egyszer történjen, még akkor is, ha több szál is megkísérelheti az inicializálást.
Windows Server 2003 és Windows XP: Alkalmazásoknak saját szinkronizálást kell biztosítaniuk az egyszeri inicializáláshoz az összekapcsolt függvények vagy más szinkronizálási mechanizmus használatával. Az egyszeri inicializálási függvények a Windows Vista és a Windows Server 2008 rendszertől kezdve érhetők el.
Az egyszeri inicializálási függvények jelentős előnyökkel járnak annak biztosításához, hogy csak egy szál hajtja végre az inicializálást:
- Ezek sebességre vannak optimalizálva.
- Ezek hozzák létre a megfelelő korlátokat a processzorarchitektúrák számára, amelyek megkövetelik őket.
- Mind a zárolt, mind a párhuzamos inicializálást támogatják.
- Elkerülik a belső zárolást, hogy a kód aszinkron módon vagy szinkron módon működjön.
A rendszer egy átlátszatlan INIT_ONCE struktúrán keresztül kezeli az inicializálási folyamatot, amely adatokat és állapotinformációkat tartalmaz. A hívó lefoglalja ezt a struktúrát, és inicializálja az InitOnceInitialize meghívásával (a struktúra dinamikus inicializálásához), vagy az állandó INIT_ONCE_STATIC_INIT hozzárendelésével a struktúraváltozóhoz (a struktúra statikus inicializálásához). Az egyszeri inicializálási struktúrában tárolt adatok kezdetben NULL értékűek, állapota pedig nem inicializálódik.
Az egyszeri inicializálási struktúrák nem oszthatók meg a folyamatok között.
Az inicializálást végrehajtó szál opcionálisan beállíthat egy olyan környezetet, amely az inicializálás befejezése után elérhető a hívó számára. A környezet lehet szinkronizálási objektum, de lehet érték vagy adatstruktúra is. Ha a környezet érték, akkor az alacsony sorrendű INIT_ONCE_CTX_RESERVED_BITS nullának kell lennie. Ha a környezet adatstruktúra, az adatstruktúrát DWORDkell igazítottnak lennie. A környezet az initOnceBeginInitializevagy InitOnceExecuteOnce függvény lpContext kimenetiparaméterében lesz visszaadva a hívónak.
Az egyszeri inicializálás szinkronizálva vagy aszinkron módon is elvégezhető. Választható visszahívási függvény használható szinkron egyszeri inicializáláshoz.
Szinkron egyszeri inicializálás
Az alábbi lépések a visszahívási függvényt nem használó szinkron egyszeri inicializálást ismertetik.
- A InitOnceBeginInitialize függvény sikeres meghívásához először megkezdődik az egyszeri inicializálás. Szinkron egyszeri inicializálás esetén InitOnceBeginInitialize a INIT_ONCE_ASYNC jelző nélkül kell meghívni.
- Az inicializálást megkísérlõ további szálak mindaddig le lesznek tiltva, amíg az első szál be nem fejeződik vagy meghiúsul. Ha az első szál meghiúsul, a következő szál megkísérli az inicializálást, és így tovább.
- Amikor az inicializálás befejeződött, a szál meghívja a InitOnceComplete függvényt. A szál létrehozhat egy szinkronizálási objektumot (vagy más környezeti adatot), és megadhatja azt az InitOnceComplete függvény lpContext paraméterében.
- Ha az inicializálás sikeres, az egyszeri inicializálási struktúra állapota inicializálva lesz, és a lpContext leíró (ha van ilyen) az inicializálási struktúrában lesz tárolva. A későbbi inicializálási kísérletek ezeket a környezeti adatokat adják vissza. Ha az inicializálás sikertelen, az adatok null .
Az alábbi lépések a visszahívási függvényt használó szinkron egyszeri inicializálást ismertetik.
- A InitOnceExecuteOnce függvény sikeres meghívásának első szála egy alkalmazás által definiált InitOnceCallback visszahívási függvényre és a visszahívási függvény által igényelt adatokra mutat. Ha a hívás sikeres, a InitOnceCallback visszahívási függvény fut.
- Az inicializálást megkísérlõ további szálak mindaddig le lesznek tiltva, amíg az első szál be nem fejeződik vagy meghiúsul. Ha az első szál meghiúsul, a következő szál megkísérli az inicializálást, és így tovább.
- Ha az inicializálás befejeződött, a visszahívási függvény visszatér. A visszahívási függvény létrehozhat egy szinkronizálási objektumot (vagy más környezeti adatot), és megadhatja azt a Környezeti kimeneti paraméterben.
- Ha az inicializálás sikeres, az egyszeri inicializálási struktúra állapota inicializálva lesz, és a Környezeti leíró (ha van ilyen) az inicializálási struktúrában lesz tárolva. A későbbi inicializálási kísérletek ezeket a környezeti adatokat adják vissza. Ha az inicializálás sikertelen, az adatok null .
Aszinkron egyszeri inicializálás
Az alábbi lépések az aszinkron egyszeri inicializálást ismertetik.
- Ha egyszerre több szál is megpróbálja inicializálni az inicializálást az InitOnceBeginInitialize meghívásával INIT_ONCE_ASYNC, a függvény az összes szál esetében sikeres lesz, ha az fPending paraméter értéke true . Csak egy szál lesz sikeres az inicializáláskor; más egyidejű kísérletek nem módosítják az inicializálás állapotát.
- Amikor InitOnceBeginInitialize ad vissza, a fPending paraméter az inicializálás állapotát jelzi:
- Ha HAMIS, egy szál inicializálása sikeres volt. A többi szálnak törölnie kell az általuk létrehozott környezeti adatokat, és a környezeti adatokat az InitOnceBeginInitializelpContext kimeneti paraméterében kell használnia.
- Ha fPendingTRUE, az inicializálás még nem fejeződött be, és a többi szálnak folytatódnia kell.
- Minden szál meghívja az InitOnceComplete függvényt. A szál igény szerint létrehozhat egy szinkronizálási objektumot (vagy más környezeti adatokat), és megadhatja azt az InitOnceCompletelpContext paraméterében.
- Amikor InitOnceComplete ad vissza, a visszatérési értéke azt jelzi, hogy a hívószál sikeres volt-e az inicializáláskor.
- Ha InitOnceComplete sikeres, a hívószál inicializálása sikeres volt. Az egyszeri inicializálási struktúra állapota inicializálásra változik, és a lpContext leíró (ha van ilyen) az inicializálási struktúrában van tárolva.
- Ha InitOnceComplete sikertelen, egy másik szál inicializálása sikerült. A hívószálnak törölnie kell a létrehozott környezeti adatokat, és meghívnia InitOnceBeginInitialize az INIT_ONCE_CHECK_ONLY használatával az egyszeri inicializálási struktúrában tárolt környezeti adatok lekéréséhez.
One-Time inicializálásának meghívása több helyről
Egy INIT_ONCE szerkezet által védett egyszeri inicializálás több helyről is elvégezhető; különböző visszahívások továbbíthatók az egyes helyekről, és a visszahívással és anélkül történő szinkronizálás vegyes lehet. Az inicializálás továbbra is garantáltan csak egyszer sikeres lesz.
Az aszinkron és szinkron inicializálás azonban nem keverhető össze: az aszinkron inicializálási kísérlet után a szinkron inicializálás indítása sikertelen lesz.
Kapcsolódó témakörök
-
One-Time inicializálási használata