多线程情况下初始化一次(InitOnceExecuteOnce)

来源:互联网 发布:nba球员场均数据排名 编辑:程序博客网 时间:2024/05/22 22:25

下面的例子展示了如何使用一次初始化(one-time initialization)

同步

在这个例子中, 全局变量g_InitOnce是one-time initialization结构体.它被初始化为INIT_ONCE_STATIC_INIT值.

OpenEventHandleSync 函数返回唯一的事件句柄. 它通过调用InitOnceExecuteOnce 函数去执行包含在InitHandleFunction 回调函数中的初始化代码. 如果回调函数执行成功,OpenEventHandleAsync 通过lpContext变量返回事件对象句柄; 否则,返回INVALID_HANDLE_VALUE.

InitHandleFunction 函数是 one-time initialization 回调函数. InitHandleFunction 调用CreateEvent 函数去创建一个事件对象句柄 并且通过lpContext 变量返回.

#define _WIN32_WINNT 0x0600#include <windows.h>// Global variable for one-time initialization structureINIT_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 onceHANDLE 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是one-time initialization结构体.它被初始化为INIT_ONCE_STATIC_INIT值.

 OpenEventHandleAsync函数返回唯一的事件句柄.OpenEventHandleAsync 调用InitOnceBeginInitialize 函数进入初始化状态.

如果函数调用成功, 代码通过检查 fPending 变量的值来决定是否创建一个事件对象句柄或返回另外一个线程创建的句柄. 如果 fPending变量FALSE,则证明初始化已经完成,因此OpenEventHandleAsync 通过lpContext 变量返回事件对象句柄. 否则, 它调用CreateEvent 函数去创建一个事件对象句柄 和调用InitOnceComplete 函数去完成这次初始化操作.

如果调用InitOnceComplete 函数成功,OpenEventHandleAsync 函数返回新的事件对象句柄. 否则, 它关闭事件对象句柄和调用InitOnceBeginInitialize 函数并且传入参数INIT_ONCE_CHECK_ONLY 去决定是否初始化失败或者被另外一个线程完成.

如果初始化操作被另外一个线程完成, OpenEventHandleAsync 函数通过lpContext变量返回另外一个线程创建的事件对象句柄. 否则,返回INVALID_HANDLE_VALUE.

#define _WIN32_WINNT 0x0600#include <windows.h>// Global variable for one-time initialization structureINIT_ONCE g_InitOnce = INIT_ONCE_STATIC_INIT; // Static initialization// Returns a handle to an event object that is created only onceHANDLE 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;  }}


0 0
原创粉丝点击