The standard example for std::call_once on cppreference.com describes the behavior for exceptional calls that way, that to my understanding other threads wait for the first entering the std::call_once and in case of an exception the next thread will try to execute the std::call_once. While online compilers confirm this behavior, I cannot reproduce it locally. For the minimal example
#include <iostream>
#include <thread>
#include <mutex>
std::once_flag flag;
void may_throw_function(bool do_throw)
{
if (do_throw) {
std::cout << "throw: call_once will retry\n";
throw std::exception();
}
std::cout << "Didn't throw, call_once will not attempt again\n";
}
void do_once(bool do_throw)
{
try {
std::call_once(flag, may_throw_function, do_throw);
}
catch (...) {}
}
int main()
{
std::thread t1(do_once, true);
std::thread t2(do_once, true);
std::thread t3(do_once, false);
std::thread t4(do_once, true);
t1.join();
t2.join();
t3.join();
t4.join();
}
copied from cppreference.com the execution is stuck after the first throw and runs forever
Compilation is done with g++-5 -std=c++14 source.cpp -pthread (version g++ (Ubuntu 5.4.0-6ubuntu1~16.04.11) 5.4.0 20160609) or clang++-6.0 source.cpp -pthread (version clang version 6.0.0-1ubuntu2~16.04.1 (tags/RELEASE_600/final)).
Putting more output into the code shows, that all threads are started, but only the threads that throws first ever ends. All others seems to wait before the std::call_once statement. Hence my question: Is the notification of threads that are waiting for the first thread to finish guaranteed?
Aucun commentaire:
Enregistrer un commentaire