std::call_once coordinates one-time initialization across threads. Pair a std::once_flag with each initialization, then pass the flag and a function or other callable to std::call_once. When the call returns, the initialized data is available with the required synchronization. section 3.3.1
std::shared_ptr<some_resource> resource_ptr;
std::once_flag resource_flag; #1
void init_resource()
{
resource_ptr.reset(new some_resource);
}
void foo()
{
std::call_once(resource_flag,init_resource); #2
resource_ptr->do_something();
}
A shared resource is initialized by one callable; each caller uses call_once before accessing it. section 3.3.1
The same flag can protect a class member initialized on the first call to either of two methods. This avoids manually checking a shared pointer outside the lock, which can introduce a data race and undefined behavior. Where one-time initialization fits, call_once typically has lower overhead than explicit mutex locking, especially after initialization is complete. section 3.3.1
Listing 3.12. Thread-safe lazy initialization of a class member using std::call_once
class X
{
private:
connection_info connection_details;
connection_handle connection;
std::once_flag connection_init_flag;
void open_connection()
{
connection=connection_manager.open(connection_details);
}
public:
X(connection_info const& connection_details_):
connection_details(connection_details_)
{}
void send_data(data_packet const& data) #1
{
std::call_once(connection_init_flag,&X::open_connection,this); #2
connection.send_data(data);
}
data_packet receive_data() #3
{
std::call_once(connection_init_flag,&X::open_connection,this); #2
return connection.receive_data();
}
};
!@%STYLE%@!
{"css":"{\"css\": \"font-weight: bold;\"}","target":"[[{\"line\":14,\"ch\":72},{\"line\":14,\"ch\":74}],[{\"line\":16,\"ch\":72},{\"line\":16,\"ch\":74}],[{\"line\":21,\"ch\":72},{\"line\":21,\"ch\":74}],[{\"line\":19,\"ch\":72},{\"line\":19,\"ch\":74}],[{\"line\":16,\"ch\":72},{\"line\":16,\"ch\":74}],[{\"line\":21,\"ch\":72},{\"line\":21,\"ch\":74}]]"}
!@%STYLE%@!
Both send_data and receive_data use the same flag to ensure the connection is opened before either method uses it. section 3.3.1


