Впервые появилась необходимость использования std::call_once в плюсах (до этого как-то не приходилось совсем). Чтобы поэкспериментировать как работает написал небольшой сэмпл:
#include <iostream>
#include <mutex>
#include <chrono>
#include <thread>
#include <vector>
std::once_flag once_work_call;
std::mutex cout_lock;
void init()
{
std::this_thread::sleep_for(std::chrono::seconds(5));
std::scoped_lock guard(cout_lock);
std::cout << "init finished" << std::endl;
}
void work(int i)
{
std::call_once(once_work_call, init);
std::scoped_lock guard(cout_lock);
std::cout << "finish work [" << i << "]" << std::endl;
}
int main()
{
std::vector<std::thread> threads;
for(int i = 0; i < 5; ++i)
{
threads.emplace_back(work, i);
}
for(auto& t: threads)
{
t.join();
}
return 0;
}
Пока функция, переданная в std::call_once (в данном случае init), успешно не отработает на одном из потоков, остальные потоки будут ожидать, когда дойдут до вызова std::call_once, понятное дело что вызова std::call_once с одним и тем же флагом (в данном случае once_work_call).