I\'m a bit confused about the purpose of std::call_once
. To be clear, I understand exactly what std::call_once
does, and how to use it. It\'
If you read this you'll see that std::call_once
makes no guarantee about data-races, it's simply a utility function for performing an action once (which will work across threads). You shouldn't presume that is has anything close to the affect of a mutex.
as an example:
#include
#include
static std::once_flag flag;
void f(){
operation_that_takes_time();
std::call_once(flag, [](){std::cout << "f() was called\n";});
}
void g(){
operation_that_takes_time();
std::call_once(flag, [](){std::cout << "g() was called\n";});
}
int main(int argc, char *argv[]){
std::thread t1(f);
std::thread t2(g);
t1.join();
t2.join();
}
could print both f() was called
and g() was called
. This is because in the body of std::call_once
it will check whether flag
was set then set it if not then call the appropriate function. But while it is checking or before it set flag
another thread may call call_once
with the same flag and run a function at the same time. You should still protect calls to call_once
with a mutex if you know another thread may have a data race.
I found a link to the proposal for the std::call_once
function and thread library which states that concurrency is guaranteed to only call the function once, so it should work like a mutex (y)
More specifically:
If multiple calls to call_once with the same flag are executing concurrently in separate threads, then only one thread shall call func, and no thread shall proceed until the call to func has completed.
So to answer your question: yes, other threads will be blocked until the calling thread returns from the specified functor.