同步
在这个例子中, 全局变量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 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
是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 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;
}
}