I wrote a small test project to see if std::call_once blocks while executing callable. Output of the project allows to assume that call_once has 2 behaviours: it blocks on detached threads and does not on joined. I strongly suspect that it can not be true, but there is no other conclusion I can make, please guide me to the correct one.
using namespace std;
once_flag f;
mutex cout_sync;
void my_pause()
{
volatile int x = 0;
for(int i=0; i<2'000'000'000; ++i) { x++; }
}
void thr(int id)
{
auto start = chrono::system_clock::now();
call_once(f, my_pause);
auto end = chrono::system_clock::now();
scoped_lock l{cout_sync};
cout << "Thread " << id << " finished in " << (static_cast<chrono::duration<double>>(end-start)).count() << " sec" << endl;
}
int main()
{
vector<thread> threads;
for(int i=0; i<4; i++)
{
threads.emplace_back(thr, i);
threads.back().join();
}
return 0;
}
Output:
Thread 0 finished in 4.05423 sec
Thread 1 finished in 0 sec
Thread 2 finished in 0 sec
Thread 3 finished in 0 sec
Changing threads to detached:
for(int i=0; i<4; i++)
{
threads.emplace_back(thr, i);
threads.back().detach();
}
this_thread::sleep_for(chrono::seconds(5));
Output:
Thread 0 finished in 4.08223 sec
Thread 1 finished in 4.08223 sec
Thread 3 finished in 4.08123 sec
Thread 2 finished in 4.08123 sec
Visual Studio 2017