我使用的是C ++ OpenCL包装程序,我想知道为什么我的程序崩溃了。我发现对的任何调用std::call_once均引发错误。
std::call_once
#include <mutex> int main() { static std::once_flag f; std::call_once(f, []{}); }
程序输出:
terminate called after throwing an instance of 'std::system_error' what(): Unknown error -1
这是的输出g++ -v:
g++ -v
Using built-in specs. COLLECT_GCC=g++ COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-pc-linux-gnu/8.1.1/lto-wrapper Target: x86_64-pc-linux-gnu Configured with: /build/gcc/src/gcc/configure --prefix=/usr –libdir=/usr/lib –libexecdir=/usr/lib –mandir=/usr/share/man –infodir=/usr/share/info --with-bugurl=https://bugs.archlinux.org/ –enable-languages=c,c,ada,fortran,go,lto,objc,obj-c –enable-shared –enable-threads=posix –enable-libmpx –with-system-zlib –with-isl –enable-__cxa_atexit –disable-libunwind-exceptions –enable-clocale=gnu –disable-libstdcxx-pch –disable-libssp –enable-gnu-unique-object –enable-linker-build-id –enable-lto –enable-plugin –enable-install- libiberty –with-linker-hash-style=gnu –enable-gnu-indirect-function –enable-multilib –disable-werror –enable-checking=release –enable- default-pie –enable-default-ssp Thread model: posix gcc version 8.1.1 20180531 (GCC)
Using built-in specs. COLLECT_GCC=g++ COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-pc-linux-gnu/8.1.1/lto-wrapper Target: x86_64-pc-linux-gnu Configured with: /build/gcc/src/gcc/configure --prefix=/usr
–libdir=/usr/lib –libexecdir=/usr/lib –mandir=/usr/share/man –infodir=/usr/share/info --with-bugurl=https://bugs.archlinux.org/ –enable-languages=c,c,ada,fortran,go,lto,objc,obj-c –enable-shared –enable-threads=posix –enable-libmpx –with-system-zlib –with-isl –enable-__cxa_atexit –disable-libunwind-exceptions –enable-clocale=gnu –disable-libstdcxx-pch –disable-libssp –enable-gnu-unique-object –enable-linker-build-id –enable-lto –enable-plugin –enable-install- libiberty –with-linker-hash-style=gnu –enable-gnu-indirect-function –enable-multilib –disable-werror –enable-checking=release –enable- default-pie –enable-default-ssp Thread model: posix gcc version 8.1.1 20180531 (GCC)
正如Praetorian在评论中所说,std::call_once需要调用系统线程库。更具体地说,它将调用__gthread_once。如果可执行文件未链接到pthread,则该函数将返回-1,然后将引发异常。
__gthread_once
-1
要制作程序-pthread,必须将启用了pthread的选项同时传递给编译器和链接器,如gcc文档中所述。-lpthread有时仅通过链接是不够的,不仅仅是因为附加宏。对于CMake用户,有一个现成的模块,可以帮助添加对pthread(或任何系统线程库)的支持,该支持可以这样使用:
-pthread
-lpthread
find_package(Threads REQUIRED) target_link_libraries(myTarget PRIVATE Threads::Threads)
如有必要,这将添加所有必需的编译和链接标志。