使用One-Time初始化

以下示例演示如何使用一次性初始化函数。

同步示例

在此示例中, g_InitOnce 全局变量是一次性初始化结构。 它是使用 INIT_ONCE_STATIC_INIT 静态初始化

函数 OpenEventHandleSync 返回只创建一次的事件的句柄。 它调用 InitOnceExecuteOnce 函数来执行回调函数中包含的 InitHandleFunction 初始化代码。 如果回调函数成功, OpenEventHandleSync 则返回 lpContext 中返回的事件句柄;否则,它将返回 INVALID_HANDLE_VALUE

函数 InitHandleFunction一次性初始化回调函数InitHandleFunction 调用 CreateEvent 函数以创建事件,并在 lpContext 参数中返回事件句柄。

#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;
  }
}

异步示例

在此示例中, g_InitOnce 全局变量是一次性初始化结构。 它是使用 INIT_ONCE_STATIC_INIT 静态初始化

函数 OpenEventHandleAsync 返回只创建一次的事件的句柄。 OpenEventHandleAsync 调用 InitOnceBeginInitialize 函数以进入初始化状态。

如果调用成功,代码将检查 fPending 参数的值,以确定是创建事件还是只返回由另一个线程创建的事件的句柄。 如果 fPendingFALSE,则初始化已完成,因此 OpenEventHandleAsync 返回 lpContext 参数中返回的事件句柄。 否则,它会调用 CreateEvent 函数来创建 事件,并调用 InitOnceComplete 函数来完成初始化。

如果对 InitOnceComplete 的调用成功, OpenEventHandleAsync 则返回新的事件句柄。 否则,它会关闭事件句柄,并使用 INIT_ONCE_CHECK_ONLY 调用 InitOnceBeginInitialize,以确定初始化是失败还是由另一个线程完成。

如果初始化由另一个线程完成, OpenEventHandleAsync 则 返回 lpContext 中返回的事件句柄。 否则,它将返回 INVALID_HANDLE_VALUE

#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;
  }
}

一次性初始化