簡體   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