#include <iostream>
#include <mutex>
std::once_flag flag;
uint32_t count = 0;
void init()
{
count = 1;
}
void call_once_func()
{
std::call_once(flag, init);
}
int main(int argc, char **argv)
{
call_once_func();
call_once_func();
call_once_func();
printf("%u\n", count);
return 0;
}
g++ 7.5.0
g++ test_std_call_once.cc
执行a.out会抛出异常
此时需要主动添加一个编译选项-pthread
g++ test_std_call_once.cc -pthread
即可正常使用
BUG描述:https://gcc.gnu.org/bugzilla/show_bug.cgi?id=55394
没有链接编译时也不会报错,运行时异常描述也毫无作用,无法分析。
其实问题就出现在有没有链接pthread库,gcc使用的pthread_once函数执行,故需要链接pthread库
但是使用-lpthread会发现它链接不上,-l只影响链接阶段,让其在pthread找到使用的符号文件,如果没有找到,则忽略-lpthread。在gcc代码中使用static __typeof(pthread_key_create) __gthrw___pthread_key_create __attribute__ ((__weakref__("__pthread_key_create")));
判断是否支持多线程,弱引用意味着如果在链接时找不到 __pthread_key_create,这个引用不会导致链接错误,而是会被替换为 NULL 或者其他默认行为。故__gthread_active_p
返回为false,导致__gthread_once
返回-1,最终抛出异常。当代码中存在pthread库的符号时,使用-lpthread将会正常调用call_once。
gcc -lpthread和gcc -pthread的区别
故以后代码中可以使用-pthread代替-lpthread