繁体   English   中英

在异常调用之后是std :: call_once保证线程的通知

[英]Is notification of threads guaranteed for std::call_once after exceptional call

cppreference.comstd::call_once的标准示例描述了异常调用的行为,这是我理解的其他线程等待第一次进入std::call_once ,如果是异常,下一个线程将尝试执行std::call_once 虽然在线编译器确认了这种行为,但我无法在本地重现它。 对于最小的例子

#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();
}

cppreference.com复制后,执行在第一次投掷后被卡住并永远运行

编译使用g++-5 -std=c++14 source.cpp -pthread (版本g++ (Ubuntu 5.4.0-6ubuntu1~16.04.11) 5.4.0 20160609 )或clang++-6.0 source.cpp -pthread (版本) clang version 6.0.0-1ubuntu2~16.04.1 (tags/RELEASE_600/final) )。

将更多输出放入代码中会显示所有线程都已启动,但只有先抛出的线程才会结束。 所有其他人似乎都在std::call_once语句之前等待。 因此我的问题是:等待第一个线程的线程通知是否有保证?

是否等待第一个线程完成保证的线程通知?

没有涉及通知,但如果我将您的问题解释为:

t4.join()保证返回吗?

是的。

[thread.once.callonce]

 template<class Callable, class... Args> void call_once(once_flag& flag, Callable&& func, Args&&... args); 

效果 :不调用其func的call_once的执行是被动执行。
调用其func的call_once的执行是一个活动执行。 活动执行应调用INVOKE(​std::forward<Callable>(func), std::forward<Args>(args)...)
如果对func的这种调用抛出异常,则执行异常,否则返回。
异常执行应将异常传播给call_once的调用者。 在任何给定的once_flagcall_once所有执行中:最多一个应该是返回执行; 如果有返回执行,则应该是最后一次执行; 只有在返回执行时才会执行被动执行

同步 :对于任何给定的once_flag: 所有活动执行都按总顺序发生 ; 活动执行的完成与此总订单中下一个的开始同步; 并且返回的执行与所有被动执行的返回同步。

一个call_once 只有 1人将不被执行call_once返回(:没扔的意思)。 由于遵守了总订单,因此可以保证:

  • t1是主动例外执行或被动执行;
  • t2是主动例外执行或被动执行;
  • t3是主动返回执行;
  • t4是主动例外执行或被动执行;

并且由于被动执行返回,因此保证t4返回。


用户cpplearner报告pthread_once的错误使问题中的程序挂起( 演示 )。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM