2017-01-18 48 views
11

鑑於這段代碼:的std :: call_once的()掛在第二個電話後可贖回扔在第一次調用

#include <mutex> 
#include <iostream> 

void f(bool doThrow) { 
    if (doThrow) { 
     std::cout << "Throwing" << std::endl; 
     throw 42; 
    } 
    std::cout << "Not throwing" << std::endl; 
} 

std::once_flag flag; 

void g(bool doThrow) { 
    try { 
     std::call_once(flag, f, doThrow); 
     std::cout << "Returning" << std::endl; 
    } catch (int i) { 
     std::cout << "Caught " << i << std::endl; 
    } 
} 

int main() { 
    std::once_flag flag; 
    g(true); 
    g(true); 
    g(false); 
    g(true); 
    g(false); 
} 

g++ -std=c++11 -pthread -ggdb編譯我得到的輸出:

Throwing 
Caught 42 

之後該進程掛起:

#0 0x000003fff7277abf in futex_wait (private=0, expected=1, futex_word=0x2aaaacad144 <flag>) at ../sysdeps/unix/sysv/linux/futex-internal.h:61 
#1 futex_wait_simple (private=0, expected=1, futex_word=0x2aaaacad144 <flag>) at ../sysdeps/nptl/futex-internal.h:135 
#2 __pthread_once_slow (once_control=0x2aaaacad144 <flag>, init_routine=0x3fff7a8d870 <std::__once_proxy()>) at pthread_once.c:105 
#3 0x000002aaaaaab06f in __gthread_once (__once=0x2aaaacad144 <flag>, __func=0x3fff7a8d870 <std::__once_proxy()>) at /usr/lib/gcc/x86_64-pc-linux-gnu/5.4.0/include/g++-v5/x86_64-pc-linux-gnu/bits/gthr-default.h:699 
#4 0x000002aaaaaab6c8 in std::call_once<void (&)(bool), bool&> (__once=..., [email protected]: {void (bool)} 0x2aaaaaab08c <f(bool)>) at /usr/lib/gcc/x86_64-pc-linux-gnu/5.4.0/include/g++-v5/mutex:738 
#5 0x000002aaaaaab192 in g (doThrow=true) at test.cpp:17 
#6 0x000002aaaaaab287 in main() at test.cpp:27 

但是,當編譯clang++ -std=c++11 -pthread -ggdb我得到︰

Throwing 
Caught 42 
Throwing 
Caught 42 
Not throwing 
Returning 
Returning 
Returning 

據我所知,這似乎是正確的行爲。

這是一個海灣合作委員會的bug,只是我對std::call_once的語義困惑,或者是我的代碼不正確?

+0

'gcc'和'g ++'不是一回事! –

+3

複製,看起來像一個錯誤。 –

+0

@ Meninx-メネンックス所以呢?一個是另一個的一部分。 – user2079303

回答

7

這看起來是GNU C++庫中的一個bug。


當然這是因爲即使是默認的,如果您嘗試使用所提供的在線編譯器(Coliru):)它使用並行線程

這個錯誤發生在G ++ Linux實現std::call_onceexample from cppreference將掛起的錯誤。我感到困惑的是,this Wandbox example運行得很好。我檢查的libstdc++版本:

  • Wandbox:GLIBCXX: 20130411
  • Coliru:GLIBCXX: 20161221

因此,我認爲這是一個錯誤libstdc++,大概this one,或者更準確地說this one

相關問題