为什么glibc和pthread库都定义了相同的API? [英] Why glibc and pthread library both defined same APIs?

查看:346
本文介绍了为什么glibc和pthread库都定义了相同的API?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么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


解决方案

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



如果你寻找 pthread_create ,您会发现它只存在于 libpthread.so 中 - 这意味着程序必须链接到 libpthread.so 来实际创建线程,但可以使用互斥锁和条件变量在只有链接到 libc.so 的单线程程序中。这对于共享内存中的进程间互斥和进程间条件变量很有用,并且用于与单独进程同步。 (更正如下Zan Lynx的评论)。
$ b 链接到 libpthread.so libc.so 即使它们都定义了符号。 ELF链接器允许多个共享库包含相同符号的定义,链接器将选择它所看到的第一个并将其用于该符号的所有引用,这称为符号插入。允许定义多个符号的另一个功能是,如果一个图书馆包含弱符号,这将是由具有相同名称的非弱符号覆盖。在这种情况下,中的两个库的定义是相同的,所以使用哪一个并不重要> libpthread.so 会覆盖 libc.so 。如果你使用 LD_DEBUG 并改变链接器参数的顺序,你应该能够看到符号实际被发现的库。



除了定义相同符号的两个库之外,每个库都有两个符号定义,不同的符号版本 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 ,并将使用该符号。

Why glibc and pthread library both defined same APIs ? Here is the snapshot

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

解决方案

libpthread.so is part of glibc too, and they both contain (identical) definitions of some symbols.

If you look for pthread_create instead you'll see that it's only present in libpthread.so -- this means programs must link to libpthread.so to actually create threads, but can use mutexes and condition variables in single-threaded programs that only link to libc.so. That's useful for interprocess mutexes and interprocess condition variables that live in shared memory and are used to synchronise with separate processes. (corrections thanks to Zan Lynx's comment below).

It's not a problem to link to both libpthread.so and libc.so even though they both define the symbol. ELF linkers allows several shared libraries to contain definitions of the same symbol and the linker will choose the first one it sees and use it for all references to that symbol, this is called symbol interposition. Another feature that allows multiple symbols to be defined is if one library contains weak symbols which will be overidden by non-weak symbols with the same name. In this case the definitions in the two libraries are identical, so it doesn't matter which is used libpthread.so override those in libc.so. If you use LD_DEBUG and change the order of arguments to the linker you should be able to see which library the symbol actually gets found in.

As well as the two libraries defining the same symbol, each library has two definitions of the symbol, with different symbol versions, GLIBC_2.0 and GLIBC_2.3.2. This symbol versioning allows multiple definitions to co-exist in the same library so that new, improved versions of the function to be added to the library without breaking code that is linked against the old implementation. This allows the same shared library to work for applications using LinuxThreads and applications using NPTL. The default symbol that a reference will be bound to when linking to the library is pthread_cond_signal@GLIBC_2.3.2 which corresponds to the NPTL implementation of that function (NPTL was first included in glibc 2.3.2). The older symbol, pthread_cond_signal@GLIBC_2.0, is the older LinuxThreads implementation that was the default before NPTL was provided. Applications linked against older (pre-2.3.2) versions of glibc will be bound to pthread_cond_signal@GLIBC_2.0 and will use that symbol.

这篇关于为什么glibc和pthread库都定义了相同的API?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆