liveBook · Manning

Call_once

As explained in Modern C, Third Edition

call_once is a C threads-library function that invokes a callback at most once for a specified once-control object, coordinating concurrent callers.

call_once coordinates one-time initialization across threads. A once_flag object records whether its callback has run; concurrent callers using that flag wait until initialization finishes, then continue with the initialized object. section 20.2 section 21.2

Initialize a shared error log

Declare an initially unused stream, a once_flag initialized with ONCE_FLAG_INIT, and an initialization callback. Before every use, call call_once(&errlog_flag, errlog_fopen); the callback can seed randomness, construct a filename, open the stream, and enable line buffering. After call_once returns, the caller can use errlog, while other threads are synchronized with the same completed initialization. section 20.2 section 21.2

void call_once(once_flag* flag, void cb(void));

Use the compact declaration to see the flag-and-callback interface: void call_once(once_flag* flag, void cb(void)); section 20.2

The first call with a given flag is special: it executes the callback and acts as a release operation. Later calls acquire that flag, making the callback's writes visible to their threads. Prefer compile-time or main-thread initialization when possible; call_once serves dynamic initialization that cannot be arranged before concurrency begins. section 20.8 section 21.2

TAKEAWAY: Pair every access to a lazily initialized shared object with the same once_flag and initialization callback, and use the object only after call_once returns. section 20.2

How Modern C, Third Edition covers it

How deep it goes
Explains the API, a shared-stream example, waiting behavior, and release-acquire visibility, but not callback failure handling.
Examples
Uses a lazily opened error log whose filename, stream, and buffering are initialized by one callback.
What it assumes
Assumes C threads and shared-object basics while teaching the once_flag protocol and its synchronization effect.
What you can do after
Apply call_once to publish a correctly initialized shared object across concurrent callers.
How it connects
Connects dynamic initialization with once_flag, shared data, threads, release-acquire operations, and atexit cleanup.

Also explained in

Compare how 3 books explain call_once →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Modern C, Third Edition. The section links point to the parts of the book it draws on.