为什么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
答案 0 :(得分:12)
libpthread.so
也是glibc的一部分,它们都包含某些符号的(相同)定义。
如果你寻找pthread_create
,你会发现它只出现在libpthread.so
中 - 这意味着程序必须链接到libpthread.so
才能实际创建线程,但是在仅链接到。 (感谢Zan Lynx在下面发表的评论)。libc.so
的单线程程序中使用互斥锁和条件变量。这对于存在于共享内存中并用于与单独进程同步的进程间互斥和进程间条件变量非常有用
链接到libpthread.so
和libc.so
并不是问题,即使它们都定义了符号。 ELF链接器允许多个共享库包含相同符号的定义,链接器将选择它看到的第一个,并将其用于对该符号的所有引用,这称为symbol interposition。允许定义多个符号的另一个特性是,如果一个库包含weak symbols,它将被具有相同名称的非弱符号覆盖。在这种情况下,两个库中中的定义是相同的,因此使用哪个 libpthread.so
覆盖libc.so
中的定义并不重要。如果您使用LD_DEBUG
并更改链接器的参数顺序,您应该能够看到符号实际找到的库。
除了定义相同符号的两个库外,每个库都有两个符号定义,具有不同的symbol versions,GLIBC_2.0
和GLIBC_2.3.2
。此符号版本控制允许多个定义共存于同一个库中,以便将新的,改进的函数版本添加到库中,而不会破坏与旧实现链接的代码。这允许相同的共享库适用于使用LinuxThreads的应用程序和使用NPTL的应用程序。链接到库时引用将绑定的默认符号是pthread_cond_signal@GLIBC_2.3.2
,它对应于该函数的NPTL实现(NPTL首先包含在glibc 2.3.2中)。较旧的符号pthread_cond_signal@GLIBC_2.0
是较旧的LinuxThreads实现,它是在提供NPTL之前的默认实现。与旧版(2.3.2之前版本)glibc链接的应用程序将绑定到pthread_cond_signal@GLIBC_2.0
并将使用该符号。