Använda One-Time initialisering
I följande exempel visas användningen av engångsinitieringsfunktionerna.
Synkront exempel
I det här exemplet är den globala variabeln g_InitOnce
en engångsinitieringsstruktur. Den initieras statiskt med hjälp av INIT_ONCE_STATIC_INIT.
Funktionen OpenEventHandleSync
returnerar en handle till en händelse som bara skapas en gång. Den anropar funktionen InitOnceExecuteOnce för att exekvera initieringskoden som finns i återanropsfunktionen InitHandleFunction
. Om återanropsfunktionen lyckas, returnerar OpenEventHandleSync
det händelsehandtag som anges i lpContext; annars returnerar den INVALID_HANDLE_VALUE.
Funktionen InitHandleFunction
är :s engångsinitierings-återanropsfunktion.
InitHandleFunction
anropar funktionen CreateEvent för att skapa händelsen och returnerar händelsereferensen i parametern 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;
}
}
Asynkront exempel
I det här exemplet är den globala variabeln g_InitOnce
en engångsinitieringsstruktur. Den initieras statiskt med hjälp av INIT_ONCE_STATIC_INIT.
Funktionen OpenEventHandleAsync
returnerar en referens till en händelse som bara skapas en gång.
OpenEventHandleAsync
anropar funktionen InitOnceBeginInitialize för att ange initieringstillståndet.
Om anropet lyckas kontrollerar koden värdet av parametern fPending för att avgöra om händelsen ska skapas eller om den bara ska returnera ett handtag till händelsen som skapats av en annan tråd. Om fPending är FALSEhar initieringen redan avslutats, så OpenEventHandleAsync
returnerar händelsereferensen som tidigare returnerades i parametern lpContext. Annars anropas funktionen CreateEvent för att skapa händelsen och funktionen InitOnceComplete för att slutföra initieringen.
Om anropet till InitOnceComplete lyckas returnerar OpenEventHandleAsync
den nya händelsereferensen. Annars stängs händelsehandtaget och funktionen InitOnceBeginInitialize anropas med INIT_ONCE_CHECK_ONLY för att avgöra om initieringen misslyckades eller slutfördes av en annan tråd.
Om initieringen slutfördes av en annan tråd returnerar OpenEventHandleAsync
händelsereferensen som returneras i lpContext. Annars returneras 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;
}
}
Relaterade ämnen