Follow

Впервые появилась необходимость использования std::call_once в плюсах (до этого как-то не приходилось совсем). Чтобы поэкспериментировать как работает написал небольшой сэмпл:
<iostream>
<mutex>
<chrono>
<thread>
<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).

Sign in to participate in the conversation
Qoto Mastodon

QOTO: Question Others to Teach Ourselves
An inclusive, Academic Freedom, instance
All cultures welcome.
Hate speech and harassment strictly forbidden.