加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

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

发布时间:2020-12-16 06:00:52 所属栏目:百科 来源:网络整理
导读:给定这段代码: #include mutex#include iostreamvoid 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,doTh
给定这段代码:
#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,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=...,__f=@0x2aaaaaab08c: {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

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

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

解决方法

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

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

该错误发生在使用pthread的g linux实现中.令我困惑的是this Wandbox example跑得很好.我检查了libstdc的版本:

> Wandbox:GLIBCXX:20130411
> Coliru:GLIBCXX:20161221

所以我相信这是一个libstdc的bug,大概是this one,更准确地说就是this one.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读