Name | Description | Notes | Source | Availability | |||||||
---|---|---|---|---|---|---|---|---|---|---|---|
call_ |
Ensure that a function has been invoked exactly once | ? | (·) | <threads.h> |
C11 | ||||||
ONCE_ |
Initializer for
once_ |
? | M | <threads.h> |
C11 | ||||||
once_ |
Flag type to detect exactly one invocation | ? | T | <threads.h> |
C11 |
It is sometimes desirable not to initialize some shared resource until it is first requested. This lazy initialization appears easy to implement:
static bool inited = false; static void init(void) { // Initialize the shared resource. . . . inited = true; } foo_t open_foo(const char *config) { // Ensure we are set up. if (!inited) init(); // Now do our work for this call. . . . }
However, this idiom is not thread-safe, and multithreading is standard
from C11. You could build a new
thread-safe idiom using mtx_t
, but one is already provided. A
variable of type
once_
replaces the boolean flag, and a
function is provided to invoke the initialization:
#include<threads.h>
void call_once (once_flag *fp, void (*func)(void));
The idiom for lazy initialization then becomes:
static once_flag inited = ONCE_FLAG_ ; static void init(void) { // Initialize the shared resource. . . . } foo_t open_foo(const char *config) { // Ensure we are set up. call_INIT once (&inited, &init); // Now do our work for this call. . . . }
Note that if the initialization has already started, but not finished, when another attempt to start it occurs, the second attempt will block until it has finished.