Menggunakan Inisialisasi One-Time
Contoh berikut menunjukkan penggunaan fungsi inisialisasi satu kali.
Contoh Sinkron
Dalam contoh ini, variabel global g_InitOnce
adalah struktur inisialisasi satu kali. Ini diinisialisasi secara statis menggunakan INIT_ONCE_STATIC_INIT.
Fungsi OpenEventHandleSync
mengembalikan handle ke acara yang hanya dibuat sekali. Ini memanggil fungsiInitOnceExecuteOnce untuk menjalankan kode inisialisasi yang terkandung dalam fungsi panggilan balik InitHandleFunction
. Jika fungsi panggilan balik berhasil, OpenEventHandleSync
mengembalikan handle event yang dikembalikan dalam lpContext; jika tidak, ia mengembalikan INVALID_HANDLE_VALUE.
Fungsi InitHandleFunction
adalah fungsi panggilan balik inisialisasi satu kali .
InitHandleFunction
memanggil fungsi CreateEvent untuk membuat event dan mengembalikan handel event di parameter 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;
}
}
Contoh Asinkron
Dalam contoh ini, variabel global g_InitOnce
adalah struktur inisialisasi satu kali. Ini diinisialisasi secara statis menggunakan INIT_ONCE_STATIC_INIT.
Fungsi OpenEventHandleAsync
mengembalikan handel ke peristiwa yang dibuat hanya sekali.
OpenEventHandleAsync
memanggil fungsi InitOnceBeginInitialize untuk memasuki status inisialisasi.
Jika panggilan berhasil, kode memeriksa nilai parameter fPending untuk menentukan apakah akan membuat event atau hanya mengembalikan handle ke event yang dibuat oleh utas lain. Jika fPending adalah FALSE, inisialisasi sudah selesai sehingga OpenEventHandleAsync
memperlihatkan handel peristiwa yang dikembalikan dalam parameter lpContext. Jika tidak, ini memanggil fungsiCreateEvent untuk membuat peristiwa dan fungsiInitOnceComplete untuk menyelesaikan inisialisasi.
Jika panggilan ke InitOnceComplete berhasil, OpenEventHandleAsync
mengembalikan handle peristiwa baru. Jika tidak, ini menutup handle acara dan memanggil InitOnceBeginInitialize dengan INIT_ONCE_CHECK_ONLY untuk menentukan apakah inisialisasi gagal atau diselesaikan oleh thread lain.
Jika inisialisasi diselesaikan oleh utas lain, OpenEventHandleAsync
mengembalikan handle acara yang dikembalikan dalam lpContext. Jika tidak, ia mengembalikan 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;
}
}
Topik terkait