抛出了个异常,从call_once上的理解来说代码实现应该是没问题的。于是使用调试**gdb,编译+g后使用gdb调试发现了个有意思的:
使用gdb调试发现__gthread_active_ptr指针是0,然后继续执行发现___gthread_once返回的__e为0,于是继续执行if就抛了异常。__gthread_active_ptr这又是什么呢?深入研究研究 怎么看呢?既然不知道是什么我一般的操作是先看预处理部分代码,使用gcc -E参数来编译出call_once.i文件。
g++ -E call_once.cpp -o call_once.i打开call_once.i文件我发现main函数部分没有什么特别之处,我们搜索call_once可以看到它的实现。
这段代码中的 std::call_once 函数首先创建了一个可调用对象 __callable,这个对象会调用传入的函数 __f,并传入 __args 参数。然后,它将 __callable 的地址存储到 __once_callable 变量中。 接下来,通过一个 lambda 表达式将 __callable 的调用封装在 __once_call 中,这个 lambda 表达式会执行 __callable。 最后,使用底层线程库的 __gthread_once 函数来确保 __once_call 只会执行一次,即保证传入的函数 __f 只会被调用一次。 如果 __gthread_once 的返回值不为零,表示执行出现了错误,会通过 __throw_system_error 抛出系统错误。 既然是if(__e)后抛的异常,我们继续看__gthread_once的实现,搜索__gthread_once关键字,找到其实现: |