在没有线程支持的程序加载的共享库中使用C++ 11多线程

 饥饿的饮水机 发布于 2023-02-11 04:44

我目前正在尝试在一个共享库中使用C++ 11多线程,该库被加载到Linux上的主程序(用C语言编写)中.这是大型模拟程序的一部分,我无法改变有关库加载或更改主程序的任何内容.

主程序是用gcc 4.1.2编译的,我没有它的源代码(我不能用gcc 4.8.2重新编译它).

共享库使用gcc 4.8.2编译,以便使用C++ 11多线程.我正在传递编译器命令

-pthread -lpthread -std=c++11

正如在Linux下的GCC中使用std :: thread的正确链接选项中所解释的那样?

使用此配置(" -pthread -std=c++11"和gcc 4.8)编译独立测试程序在我的系统上正常工作.但是当我启动加载共享库的程序时,我得到一个异常:

Caught std::exception!
Exception Message: Enable multithreading to use std::thread: Operation not permitted

Terminating...

使用-pthread-lpthread(编辑:也只是-pthread没有-lpthread)编译参数不起作用.编译器参数是(我正在使用cook构建系统):

-pthread -std=c++11 -fmessage-length=0 -fPIC -Wchar-subscripts ...(lots of -W* here)
... -Wunused-variable -m64 -D__64BIT__ -pthread -lpthread

和链接器参数(由于构建系统而产生的重复参数):

-pthread -lpthread -std=c++11 -pthread -lpthread -std=c++11 -shared -fPIC -Wl,-Bsymbolic -Wl,--allow-shlib-undefined -pthread -lpthread

在我的库上调用ldd会给出以下输出

$ ldd calc3/build/amd64_linux26_RH5/library.so
    linux-vdso.so.1 =>  (0x00007fff4d1fd000)
    libpthread.so.0 => /lib64/libpthread.so.0 (0x00002ae6ec124000)
    libstdc++.so.6 => /afs/bb/data/d6833/util/gcc_482/lib64/libstdc++.so.6 (0x00002ae6ec340000)
    libm.so.6 => /lib64/libm.so.6 (0x00002ae6ec655000)
    libgcc_s.so.1 => /afs/bb/data/d6833/util/gcc_482/lib64/libgcc_s.so.1 (0x00002ae6ec8d8000)
    libc.so.6 => /lib64/libc.so.6 (0x00002ae6ecaef000)
    /lib64/ld-linux-x86-64.so.2 (0x00000032cb400000)

并在主程序上

$ ldd .../bin-64/main_program
    linux-vdso.so.1 =>  (0x00007fff64595000)
    libdl.so.2 => /lib64/libdl.so.2 (0x00000032cc000000)
    libz.so.1 => /usr/lib64/libz.so.1 (0x00000032cc800000)
    libc.so.6 => /lib64/libc.so.6 (0x00000032cb800000)
    /lib64/ld-linux-x86-64.so.2 (0x00000032cb400000)

pthread库链接到我的共享库,但不链接到主程序.这个答案表明你必须将pthreads链接到主程序,但是这个答案的第二个评论(由@R ..)表示没有必要(这听起来像逻辑上).

不幸的是,除了我的库使用另一个C++库作为API之外,我对整个系统的加载机制一无所知.

请注意,其他C++ 11功能可以工作(和libstdc ++.所以在我的库的依赖项中),但C++ 11多线程不是(尽管libpthread.so也在我的库的依赖项中).

使用程序本身包含的库中的线程类是可行的(这个线程类似乎也使用pthreads).

我也试过使用-fabi-version=0-fabi-version=2因为主程序是用我的库用gcc 4.1.2编译的,但它没有改变任何东西.

有什么我忽略的或者我可以使用编译器选项来使它工作吗?或者它似乎是我的程序环境的问题?欢迎任何想法.

编辑:

我尝试使用-Wl,-no-as-needed(如评论中所建议的那样),但遗憾的是它没有改变任何东西.

使用clang 3.5而不是gcc 4.8也不起作用.

只要我对主应用程序和共享库使用gcc 4.8或clang 3.5,创建一个加载共享库的小型测试应用程序(如下面@chill的答案)就可以工作(即使没有编译器标志).当使用gcc 4.1作为主程序时,主程序甚至无法加载库(它在我的'真实'应用程序中工作).我认为编译器的不同ABI可能存在问题.

直接使用pthreads pthread.h似乎工作(虽然程序目前终止pthread_join没有错误消息,但我仍然在那里测试...)

编辑2:

运行'测试程序' LD_LIBRARY_PATH=$(pwd):$LD_LIBRARY_PATH(因为gcc 4.8库路径也需要在那里,感谢@MvG)确实运行程序但是再次崩溃,但Enable multithreading to use std::thread: Operation not permitted异常.

我检查了所有其他加载的库(找到strace ./main_program 2>&1 | grep '^open(".*\.so"' [见这里 ])并用它们全部检查ldd.它们都依赖于相同的库(具有相同的路径).ldd输出(在所有这些上):

linux-vdso.so.1 =>  (0x00007fff4d3fd000)
libstdc++.so.6 => /afs/bb/data/d6833/util/gcc_482/lib64/libstdc++.so.6 (0x00002ade28774000)
libm.so.6 => /lib64/libm.so.6 (0x00002ade28ab0000)
libgcc_s.so.1 => /afs/bb/data/d6833/util/gcc_482/lib64/libgcc_s.so.1 (0x00002ade28d33000)
libc.so.6 => /lib64/libc.so.6 (0x00002ade28f49000)
/lib64/ld-linux-x86-64.so.2 (0x00000032ea200000)

(他们都不依赖于libpthread.so.0,除了我的库和另外一个(但它是相同的/lib64/libpthread.so.0))

有些库确实有更多的依赖项(它们似乎与线程无关)但似乎没有任何"冲突"依赖项(在这些库中没有依赖于同一个库的不同版本/路径).

撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有