在某些情况下,是否有任何令人信服的性能原因选择静态链接而不是动态链接?我已经听过或读过以下内容,但我对这个问题的了解不足以保证它的真实性.
1)静态链接和动态链接之间的运行时性能差异通常可以忽略不计.
2)(1)如果使用使用配置文件数据优化程序热路径的配置文件编译器,则不成立,因为使用静态链接,编译器可以优化代码和库代码.通过动态链接,您的代码可以进行优化.如果大部分时间都花在运行库代码上,那么这可能会产生很大的不同.否则,(1)仍然适用.
在各种多线程C和C++项目中,我看到-pthread标志应用于编译和链接阶段,而其他人根本不使用它,只是传递-lpthread给链接阶段.
有没有危险没有编译和链接-pthread国旗 - 即-pthread实际做什么?我主要对Linux平台感兴趣.
事实上,Linux上的-static gcc标志现在不起作用.让我引用GNU libc FAQ:
2.22.即使是静态链接的程序也需要一些我不能接受的共享库.我能做什么?
如果没有共享库,{AJ} NSS(详细信息只需输入`info libc"Name Service Switch"')将无法正常工作.NSS允许通过仅更改一个配置文件(/etc/nsswitch.conf)而不重新链接任何程序来使用不同的服务(例如NIS,文件,db,hesiod).唯一的缺点是现在静态库需要访问共享库.这由GNU C库透明地处理.
解决方案是使用--enable-static-nss配置glibc.在这种情况下,您可以创建一个仅使用服务dns和文件的静态二进制文件(为此更改/etc/nsswitch.conf).您需要明确链接所有这些服务.例如:
Run Code Online (Sandbox Code Playgroud)gcc -static test-netdb.c -o test-netdb \ -Wl,--start-group -lc -lnss_files -lnss_dns -lresolv -Wl,--end-group这种方法的问题在于您必须将使用NSS例程的每个静态程序与所有这些库链接起来.
{UD}事实上,不能再说使用此选项编译的libc正在使用NSS.没有开关了.因此,强烈 建议不要使用--enable-static-nss,因为这会使系统上程序的行为不一致.
关于这个事实,现在有什么合理的方法可以在Linux上创建一个功能齐全的静态构建,或者静态链接在Linux上完全没用?我的意思是静态构建:
如何将intel的TBB库静态链接到我的应用程序?我知道所有警告,例如调度程序的不公平负载分配,但我不需要调度程序,只需要容器,所以没关系.
无论如何我知道这可以做到,虽然它没有记录,但我现在似乎无法找到方法(尽管我在某处之前已经看过它).
那么有人知道或有任何线索吗?
谢谢
我正在实现一个使用不同内核的多线程程序,并且同时执行许多线程.每个线程都进行一次printf()调用,结果不可读.
我如何制作printf()原子,以便printf()一个线程中的printf()调用与另一个线程中的调用不冲突?
我正在开发一个std::jthread使用 g++ 10.0.1的库(C++20 中的新功能)。如果我使用共享库编译它,该库工作正常,但如果我使用静态库编译它,我会在程序结束时遇到分段错误(线程析构函数)。我已经将我的测试用例缩小到一个简单的线程创建和连接:
#include <iostream>
#include <thread>
int main(int argc, const char** argv) {
auto t = std::jthread([]() { std::cout << "OK\n"; });
t.join();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
要编译我使用:
g++-10 -o test --static -std=c++20 test.cc -lpthread
Run Code Online (Sandbox Code Playgroud)
并运行它:
% ./test
zsh: segmentation fault (core dumped) ./test
Run Code Online (Sandbox Code Playgroud)
有没有人知道这个问题可能是什么?
更新:
按照@JérômeRichard 建议的参考,我能够毫无问题地编译和运行我的小测试程序
g++-10 -o test --static -std=c++20 test.cc -lrt -pthread -Wl,--whole-archive -lpthread -Wl,--no-whole-archive
Run Code Online (Sandbox Code Playgroud)
但是,将代码更改为使用request_stop而不是join程序会再次分段错误(https://godbolt.org/z/obGN8Y)。
#include <iostream>
#include <thread>
int main() {
auto t = std::jthread([]{ …Run Code Online (Sandbox Code Playgroud) 针对 pthread 的静态链接在 Linux 上是一个困难的话题。它曾经工作包-lpthread的-Wl,--whole-archive -lpthread -Wl,--no-whole-archive(细节都可以在此找到答案)。
效果是符号(对于 pthread)是strong ,而不是 weak。从 Ubuntu 18.04 开始(在 gcc 5.4.0 和 gcc 7.4.0 之间),这种行为似乎发生了变化,pthread 符号现在总是以独立于--whole-archive选项的弱符号结束。
因此,-whole-archive配方停止工作。我的问题的目的是了解工具链(编译器、链接器、标准库)中最近发生了什么变化,以及可以采取哪些措施来恢复旧行为。
例子:
#include <mutex>
int main(int argc, char **argv) {
std::mutex mutex;
mutex.lock();
mutex.unlock();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
在以下所有示例中,使用了相同的编译命令:
g++ -std=c++11 -Wall -static simple.cpp -Wl,--whole-archive -lpthread -Wl,--no-whole-archive
Run Code Online (Sandbox Code Playgroud)
之前,与编译时-static,并行线程符号(例如,pthread_mutex_lock)表现强劲(标记为T通过nm),但现在他们是弱(W):
Ubuntu 14.04: docker run --rm -it ubuntu:14.04 bash
$ apt-get …Run Code Online (Sandbox Code Playgroud) 我已经在谷歌上搜索了很长一段时间,我没有看到任何类似的东西,所以这里是。我正在尝试创建一个小的静态链接二进制文件,它可以很容易地分布在我家庭网络上的机器上。这是一个非常小的项目,所以我试图让事情变得简单。
当我在 ARM 32 位架构上静态链接 pthread 库时,我遇到了很大的困难。令人沮丧的是,完全相同的代码在 x86 的所有版本上都可以正常工作。这是我的 test.cpp 程序:
void threader( int num ) {
std::cout << "Child Thread Starting" << std::endl;
try {
throw 20;
} catch (int e) {
std::cout << "Child Thread Success" << std::endl;
}
int x = 0;
do {
x++;
} while (true);
}
int main(int argc, char *argv[]) {
std::cout << "Main Thread Starting" << std::endl;
new std::thread(&threader, 0);
try {
throw 20;
} catch (int e) {
std::cout << "Main …Run Code Online (Sandbox Code Playgroud) 是pthread在glibc.so由弱符号实现来提供pthread存根的功能呢?
我知道有pthread.so提供类似的功能pthread在glibc.so有人说pthread在glibc只提供存根,将被明确时更换连接到lpthread.
所以我的问题是如何支持它?使用弱符号或其他技术?
是libssl类似pthread的glibc?
我在main之前得到了一个堆栈跟踪:
#include <gtest/gtest.h>
using namespace std;
int main(int argc, char **argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
Run Code Online (Sandbox Code Playgroud)
堆栈跟踪:
程序收到信号SIGSEGV,分段故障。0x0000000000000000 in ?? ()
#0 0x0000000000000000 in ?? ()
#1 0x00000000004e0b51 in std::locale::_S_initialize() ()
#2 0x00000000004e0b93 in std::locale::locale() ()
#3 0x000000000050d524 in std::ios_base::Init::Init() ()
#4 0x0000000000401581 in __static_initialization_and_destruction_0 (__initialize_p=1, __priority=65535) at /usr/include/c++/4.9/iostream:74
#5 0x00000000004015b3 in _GLOBAL__sub_I_testsmain.cpp(void) () at ../../../bdf_cpp_tests/testsmain.cpp:18
#6 0x000000000053cdd7 in __libc_csu_init ()
#7 0x000000000053c3de in generic_start_main ()
#8 0x000000000053c62a in __libc_start_main ()
#9 0x00000000004013f9 in _start ()
Run Code Online (Sandbox Code Playgroud)
这是qmake 5.7和g ++ …
c++ ×7
c ×3
linux ×3
pthreads ×3
gcc ×2
linker ×2
arm ×1
c++20 ×1
glibc ×1
googletest ×1
multiprocess ×1
performance ×1
printf ×1
tbb ×1