使用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 參數的值,以判斷是否要建立事件,或只是將控制碼傳回給另一個執行緒所建立的事件。 如果 fPending 為 FALSE,則初始化已經完成,因此會 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;
}
}
相關主題