Use call_once when shared data requires dynamic initialization that cannot be completed before threads are created. Pair the call with one once_flag and one callback; concurrent callers use the same flag before accessing the initialized object. section 18.2
void call_once(once_flag* flag, void cb(void));
!@%STYLE%@!
{"css":"{\"css\": \"font-weight: bold;\"}","target":"[[{\"line\":0,\"ch\":4},{\"line\":0,\"ch\":8}],[{\"line\":0,\"ch\":9},{\"line\":0,\"ch\":18}],[{\"line\":0,\"ch\":19},{\"line\":0,\"ch\":28}],[{\"line\":0,\"ch\":4},{\"line\":0,\"ch\":8}],[{\"line\":0,\"ch\":4},{\"line\":0,\"ch\":8}]]"}
!@%STYLE%@!
The interface takes a once_flag pointer and a callback with no arguments or return value. section 18.2
Initialize a shared error log
once_flag errlog_flag = ONCE_FLAG_INIT; void errlog_fopen(void) { /* dynamic initialization */ errlog = fopen(/* generated name */, "w"); } void report(double weird) { call_once(&errlog_flag, errlog_fopen); fprintf(errlog, "bad value %g!\n", weird); } The first call among all threads invokes errlog_fopen. Other callers wait until that invocation finishes, then use the initialized errlog without repeating the initialization. section 18.2
The once_flag tracks whether a particular call_once has occurred. It prevents later callback executions and holds concurrent callers until the one initialization callback terminates. This protects initialization, not necessarily the format or ordering of later output. section 18.2


