g ++为什么你不必链接iostream二进制文件,但对于pthread你呢?

时间:2014-07-30 12:09:04

标签: c++ multithreading dynamic-linking

如果你有一个只使用'cout'对象的非常基本的C ++程序,你可以在源文件中包含iostream,然后在编译它时你不必链接任何外部库。换句话说,你可以简单地运行

g++ main.cpp -c

g++ main.o -o program

./program

当您想要使用更复杂的对象(如线程)时,不仅包含pthread,而且当您链接程序时,您必须链接到库。

g++ main.cpp -c

g++ main.o -lpthread -o program

./program

所以我的问题是,为什么我不必链接任何库来使用所有iostream对象?

3 个答案:

答案 0 :(得分:14)

当您与g++ main.o -o program链接时,您正在链接到图书馆。默认情况下,一些库是自动链接的,链接到它们的唯一方法是传递-nodefaultlibs(或等效的)。特别是,您会在cout中找到libstdc++libc会使用ldd。这两个都默认链接。

如果您安装了ldd ./program,则可以通过运行{{1}}来验证这一点;它会直接或间接地为您提供程序与之链接的所有库的列表。

答案 1 :(得分:14)

std::cout在GCC自己的C ++标准库中定义,默认情况下g++链接到它,并且它仅依赖于标准CI / O工具,例如FILE*和基本文件I / O,在libc中提供,默认情况下gccg++也会链接到该文件。因此,默认情况下,您需要使用std::cout所需的一切。

pthread_create等函数不是C ++或C标准库的一部分,它们在单独的库libpthread中定义。 GCC默认将该库 链接,因为Pthreads不是该语言的一部分(它由不同的标准定义,POSIX,但不是语言标准),也因为链接无条件地libpthread会使许多C ++程序运行得更慢,原因如下所述。

GCC的C ++标准库在许多地方使用引用计数(例如,在std::stringstd::shared_ptr的Copy-On-Write实现中)和多线程应用程序中的引用计数更新需要使用原子指令。在非多线程应用程序中,不需要原子操作,因此如果程序是单线程的,则libstdc ++使用普通的非原子更新。它检测程序是否多线程的方式是检查程序是否链接到libpthread。因此,默认情况下,为所有程序链接到libpthread会导致库认为所有程序都是多线程的,并且总是使用较慢的原子操作,即使程序没有使用任何线程。

因此,为避免某些程序变慢,用户有责任在需要时明确链接到libpthread

在POSIX平台上std::thread是Pthreads的瘦包装器,因此同样的规则适用于类型pthread_create之类的功能:用户必须手动链接到libpthread。即使std::thread 是语言标准的一部分,但这是正确的,但是因为它是在Pthreads之上实现的,并且由于上述性能影响,用户必须手动链接到它。

答案 2 :(得分:4)

在构建gcc和g ++时,您可以指定"默认库"链接。

在一些预先构建的发行版中,他们非常友好地为你做了-lstdc ++,而某些发行版并没有。