I'm using std::call_once
in my code to initialize some shared variables only once. The calling code is inside a callback that is triggered by multiple threads.
What I'm interested to know, since I couldn't find it in the documentation is whether std::call_once
is blocking essentially as if there was a std::lock_guard
instead?
In practice it looks like this is the case.
For example, the following will print "Done"
before any print()
will be called:
#include <future>
#include <iostream>
#include <thread>
#include <mutex>
std::once_flag flag;
void print()
{
for(int i=0;i<10;i++)
{
std::cout << "Hi, my name is " << std::this_thread::get_id()
<< ", what?" << std::endl;
}
}
void do_once()
{
std::cout << "sleeping for a while..." << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(500));
std::cout << "Done" << std::endl;
}
void work()
{
std::call_once(flag, [](){ do_once(); });
print();
}
int main()
{
auto handle1 = std::async(std::launch::async, work);
auto handle2 = std::async(std::launch::async, work);
auto handle3 = std::async(std::launch::async, work);
auto handle4 = std::async(std::launch::async, work);
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
}
I'm assuming this is indeed the case (since I don't see how it could be implemented otherwise), but is this behavior guaranteed or could there be a compiler that decides that std::call_once
will indeed be called once but allow other threads to continue and just ignore this call?