A One-Time inicializálás használata

Az alábbi példák az egyszeri inicializálási függvények használatát mutatják be.

Szinkron példa

Ebben a példában a g_InitOnce globális változó az egyszeri inicializálási struktúra. Statikus inicializálása INIT_ONCE_STATIC_INIThasználatával történik.

A OpenEventHandleSync függvény egy fogópontot ad vissza egy eseményhez, amely csak egyszer jön létre. Meghívja az InitOnceExecuteOnce függvényt a InitHandleFunction visszahívási függvényben található inicializálási kód végrehajtásához. Ha a visszahívási függvény sikeres, OpenEventHandleSync visszaadja az lpContext; ellenkező esetben INVALID_HANDLE_VALUEad vissza.

A InitHandleFunction függvény az egyszeri inicializálási visszahívási függvény . InitHandleFunction meghívja a CreateEvent függvényt az esemény létrehozásához, és visszaadja az eseménykezelőt az lpContext paraméterben.

#define _WIN32_WINNT 0x0600
#include <windows.h>

// Global variable for one-time initialization structure
INIT_ONCE g_InitOnce = INIT_ONCE_STATIC_INIT; // Static initialization

// Initialization callback function 
BOOL CALLBACK InitHandleFunction (
    PINIT_ONCE InitOnce,        
    PVOID Parameter,            
    PVOID *lpContext);           

// Returns a handle to an event object that is created only once
HANDLE OpenEventHandleSync()
{
  PVOID lpContext;
  BOOL  bStatus;
  
  // Execute the initialization callback function 
  bStatus = InitOnceExecuteOnce(&g_InitOnce,          // One-time initialization structure
                                InitHandleFunction,   // Pointer to initialization callback function
                                NULL,                 // Optional parameter to callback function (not used)
                                &lpContext);          // Receives pointer to event object stored in g_InitOnce

  // InitOnceExecuteOnce function succeeded. Return event object.
  if (bStatus)
  {
    return (HANDLE)lpContext;
  }
  else
  {
    return (INVALID_HANDLE_VALUE);
  }
}

// Initialization callback function that creates the event object 
BOOL CALLBACK InitHandleFunction (
    PINIT_ONCE InitOnce,        // Pointer to one-time initialization structure        
    PVOID Parameter,            // Optional parameter passed by InitOnceExecuteOnce            
    PVOID *lpContext)           // Receives pointer to event object           
{
  HANDLE hEvent;

  // Create event object
  hEvent = CreateEvent(NULL,    // Default security descriptor
                       TRUE,    // Manual-reset event object
                       TRUE,    // Initial state of object is signaled 
                       NULL);   // Object is unnamed

  // Event object creation failed.
  if (NULL == hEvent)
  {
    return FALSE;
  }
  // Event object creation succeeded.
  else
  {
    *lpContext = hEvent;
    return TRUE;
  }
}

Aszinkron példa

Ebben a példában a g_InitOnce globális változó az egyszeri inicializálási struktúra. Statikus inicializálása INIT_ONCE_STATIC_INIThasználatával történik.

A OpenEventHandleAsync függvény egy fogópontot ad vissza egy eseményhez, amely csak egyszer jön létre. OpenEventHandleAsync meghívja az InitOnceBeginInitialize függvényt az inicializálási állapot megadásához.

Ha a hívás sikeres, a kód ellenőrzi az fPending paraméter értékét annak megállapításához, hogy létre kívánja-e hozni az eseményt, vagy egyszerűen csak egy másik szál által létrehozott eseményhez ad vissza egy leírót. Ha HAMIS, az inicializálás már megtörtént, így OpenEventHandleAsync az lpContext paraméterben visszaadott eseményleírót adja vissza. Ellenkező esetben meghívja a CreateEvent függvényt az esemény létrehozásához, az inicializálás befejezéséhez pedig az InitOnceComplete függvényt.

Ha a InitOnceComplete hívása sikeres, akkor a OpenEventHandleAsync visszaadja az új eseményfogantyút. Ellenkező esetben bezárja az eseménykezelőt, majd meghívja a InitOnceBeginInitializeINIT_ONCE_CHECK_ONLY-t annak megállapítására, hogy az inicializálás sikertelen volt-e, vagy egy másik szál által lett befejezve.

Ha az inicializálást egy másik szál fejezte be, OpenEventHandleAsync az lpContextvisszaadott eseményleírót adja vissza. Ellenkező esetben INVALID_HANDLE_VALUEad vissza.

#define _WIN32_WINNT 0x0600
#include <windows.h>

// Global variable for one-time initialization structure
INIT_ONCE g_InitOnce = INIT_ONCE_STATIC_INIT; // Static initialization

// Returns a handle to an event object that is created only once
HANDLE OpenEventHandleAsync()
{
  PVOID  lpContext;
  BOOL   fStatus;
  BOOL   fPending;
  HANDLE hEvent;
  
  // Begin one-time initialization
  fStatus = InitOnceBeginInitialize(&g_InitOnce,       // Pointer to one-time initialization structure
                                    INIT_ONCE_ASYNC,   // Asynchronous one-time initialization
                                    &fPending,         // Receives initialization status
                                    &lpContext);       // Receives pointer to data in g_InitOnce  

  // InitOnceBeginInitialize function failed.
  if (!fStatus)
  {
    return (INVALID_HANDLE_VALUE);
  }

  // Initialization has already completed and lpContext contains event object.
  if (!fPending)
  {
    return (HANDLE)lpContext;
  }

  // Create event object for one-time initialization.
  hEvent = CreateEvent(NULL,    // Default security descriptor
                       TRUE,    // Manual-reset event object
                       TRUE,    // Initial state of object is signaled 
                       NULL);   // Object is unnamed

  // Event object creation failed.
  if (NULL == hEvent)
  {
    return (INVALID_HANDLE_VALUE);
  }

  // Complete one-time initialization.
  fStatus = InitOnceComplete(&g_InitOnce,             // Pointer to one-time initialization structure
                             INIT_ONCE_ASYNC,         // Asynchronous initialization
                             (PVOID)hEvent);          // Pointer to event object to be stored in g_InitOnce

  // InitOnceComplete function succeeded. Return event object.
  if (fStatus)
  {
    return hEvent;
  }
  
  // Initialization has already completed. Free the local event.
  CloseHandle(hEvent);


  // Retrieve the final context data.
  fStatus = InitOnceBeginInitialize(&g_InitOnce,            // Pointer to one-time initialization structure
                                    INIT_ONCE_CHECK_ONLY,   // Check whether initialization is complete
                                    &fPending,              // Receives initialization status
                                    &lpContext);            // Receives pointer to event object in g_InitOnce
  
  // Initialization is complete. Return handle.
  if (fStatus && !fPending)
  {
    return (HANDLE)lpContext;
  }
  else
  {
    return INVALID_HANDLE_VALUE;
  }
}

One-Time inicializálás