Verwenden One-Time Initialisierung
Die folgenden Beispiele veranschaulichen die Verwendung der einmaligen Initialisierungsfunktionen.
Synchrones Beispiel
In diesem Beispiel ist die g_InitOnce
globale Variable die einmalige Initialisierungsstruktur. Es wird statisch mit INIT_ONCE_STATIC_INIT initialisiert.
Die OpenEventHandleSync
Funktion gibt ein Handle für ein Ereignis zurück, das nur einmal erstellt wird. Sie ruft die Funktion InitOnceExecuteOnce auf, um den in der InitHandleFunction
Rückruffunktion enthaltenen Initialisierungscode auszuführen. Wenn die Rückruffunktion erfolgreich ist, OpenEventHandleSync
gibt das in lpContext zurückgegebene Ereignishandle zurück, andernfalls wird INVALID_HANDLE_VALUE zurückgegeben.
Die InitHandleFunction
Funktion ist die einmalige Rückruffunktion für die Initialisierung.
InitHandleFunction
ruft die CreateEvent-Funktion auf, um das Ereignis zu erstellen, und gibt das Ereignishandle im lpContext-Parameter zurück.
#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;
}
}
Asynchrones Beispiel
In diesem Beispiel ist die g_InitOnce
globale Variable die einmalige Initialisierungsstruktur. Es wird statisch mit INIT_ONCE_STATIC_INIT initialisiert.
Die OpenEventHandleAsync
Funktion gibt ein Handle für ein Ereignis zurück, das nur einmal erstellt wird.
OpenEventHandleAsync
ruft die InitOnceBeginInitialize-Funktion auf, um in den Initialisierungszustand zu gelangen.
Wenn der Aufruf erfolgreich ist, überprüft der Code den Wert des fPending-Parameters , um zu bestimmen, ob das Ereignis erstellt oder einfach ein Handle an das von einem anderen Thread erstellte Ereignis zurückgegeben werden soll. Wenn fPendingfalse ist, ist die Initialisierung bereits abgeschlossen, sodass OpenEventHandleAsync
das im lpContext-Parameter zurückgegebene Ereignishandle zurückgegeben wird. Andernfalls wird die CreateEvent-Funktion zum Erstellen des Ereignisses und die InitOnceComplete-Funktion aufgerufen, um die Initialisierung abzuschließen.
Wenn der Aufruf von InitOnceComplete erfolgreich ist, OpenEventHandleAsync
gibt das neue Ereignishandle zurück. Andernfalls wird das Ereignishandle geschlossen und InitOnceBeginInitialize mit INIT_ONCE_CHECK_ONLY aufgerufen, um festzustellen, ob die Initialisierung fehlgeschlagen ist oder von einem anderen Thread abgeschlossen wurde.
Wenn die Initialisierung durch einen anderen Thread abgeschlossen wurde, OpenEventHandleAsync
gibt das in lpContext zurückgegebene Ereignishandle zurück. Andernfalls wird INVALID_HANDLE_VALUE zurückgegeben.
#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;
}
}
Zugehörige Themen