当前位置:  开发笔记 > 编程语言 > 正文

std :: call_once()在第一次调用后可调用的第二次调用时挂起

如何解决《std::call_once()在第一次调用后可调用的第二次调用时挂起》经验,为你挑选了1个好方法。

鉴于这段代码:

#include 
#include 

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 ) at ../sysdeps/unix/sysv/linux/futex-internal.h:61
#1  futex_wait_simple (private=0, expected=1, futex_word=0x2aaaacad144 ) at ../sysdeps/nptl/futex-internal.h:135
#2  __pthread_once_slow (once_control=0x2aaaacad144 , init_routine=0x3fff7a8d870 ) at pthread_once.c:105
#3  0x000002aaaaaab06f in __gthread_once (__once=0x2aaaacad144 , __func=0x3fff7a8d870 ) 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 (__once=..., __f=@0x2aaaaaab08c: {void (bool)} 0x2aaaaaab08c ) 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

据我所知,这似乎是正确的行为.

这是一个GCC错误,只是我对语义感到困惑std::call_once,或者我的代码是不正确的?



1> AMA..:

这看起来是GNU C++库中的一个错误.


当然这是一个错误,因为如果你尝试使用提供的在线编译器(Coliru),即使是std::call_once cppreference的默认示例也会挂起:)

这个bug发生在使用pthreads的g ++ linux实现中.令我困惑的是,这个Wandbox示例运行得很好.我检查了以下版本libstdc++:

Wandbox: GLIBCXX: 20130411

Coliru: GLIBCXX: 20161221

因此,我认为这是一个libstdc++错误,也许这一次,或者更准确地说这一个.

推荐阅读
echo7111436
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有