15

为什么 glibc 和 pthread 库都定义了相同的 API?这是快照

ubuntu@ubuntu:/lib$ objdump -T /lib/i386-linux-gnu/libc.so.6 |grep pthread_cond_signal
000f8360 g    DF .text  00000039  GLIBC_2.3.2 pthread_cond_signal
0012b940 g    DF .text  00000039 (GLIBC_2.0)  pthread_cond_signal

ubuntu@ubuntu:/lib$ objdump -T /lib/i386-linux-gnu/libpthread.so.0 |grep pthread_cond_signal
0000b350 g    DF .text  0000007c (GLIBC_2.0)  pthread_cond_signal
0000af90 g    DF .text  000000fc  GLIBC_2.3.2 pthread_cond_signal
4

1 回答 1

16

libpthread.so也是 glibc 的一部分,它们都包含一些符号的(相同的)定义。

如果你寻找它,pthread_create你会发现它只存在于libpthread.so- 这意味着程序必须链接到libpthread.so才能实际创建线程,但可以在仅链接到的单线程程序中使用互斥锁和条件变量libc.so。这对于存在于共享内存中并用于与单独进程同步的进程间互斥锁和进程间条件变量很有用。(更正感谢 Zan Lynx 在下面的评论)。

链接到两者都不是问题libpthread.solibc.so即使它们都定义了符号。ELF 链接器允许多个共享库包含相同符号的定义,链接器将选择它看到的第一个并将其用于对该符号的所有引用,这称为符号插入。允许定义多个符号的另一个特性是,如果一个库包含弱符号,这些符号将被同名的非弱符号覆盖。在这种情况下,两个库中的定义是相同的,因此使用哪个 libpthread.so覆盖libc.so. 如果您使用LD_DEBUG 并更改链接器的参数顺序您应该能够看到该符号实际上是在哪个库中找到的。

除了定义相同符号的两个库外,每个库都有两个符号定义,具有不同的符号版本和. 这种符号版本控制允许多个定义在同一个库中共存,以便将新的改进版本的函数添加到库中,而不会破坏与旧实现链接的代码。这允许相同的共享库为使用 LinuxThreads 的应用程序和使用 NPTL 的应用程序工作。链接到库时引用将绑定到的默认符号对应于该函数的NPTL实现(NPTL 首次包含在 glibc 2.3.2 中)。较旧的符号,GLIBC_2.0GLIBC_2.3.2pthread_cond_signal@GLIBC_2.3.2pthread_cond_signal@GLIBC_2.0, 是较旧的 LinuxThreads 实现,在提供 NPTL 之前是默认的。与旧版本(2.3.2 之前)glibc 链接的应用程序将绑定pthread_cond_signal@GLIBC_2.0并使用该符号。

于 2012-06-26T15:13:39.940 回答