pthread
是由弱符号实现的glibc.so
来提供pthread
存根函数吗?
我知道有pthread.so
提供与pthread
glibc.so
类似的功能,有人说pthread
glibc
仅提供存根,并且会在明确链接到lpthread
。
所以我的问题是如何支持它?使用弱符号或其他技术?
libssl
与pthread
中的glibc
相似?
答案 0 :(得分:6)
是的,glibc使用各种pthread函数的存根实现,因此单线程程序不必浪费周期来执行诸如锁定和解锁互斥锁之类的操作,而不必链接到不同的C库(如同什么是例如,在Microsoft世界中完成。
例如,根据POSIX,每次拨打fputc(ch, stream)
时,都会有互斥锁和解锁。如果您不想这样,请致电fputc_unlocked
。但是当你这样做时,你正在使用与线程相关的POSIX扩展;对于不使用POSIX或不使用线程API的程序,它不是一个合适的解决方法。
存根pthread功能的覆盖与真实的(在动态glibc中)不是基于弱符号。共享库机制可以覆盖非弱定义。
弱符号是一种允许在静态链接下进行符号覆盖的机制。
如果您想要上述声明的来源,请在此处输入:
“请注意,DSO中的定义很弱没有效果。弱定义只在静态链接中起作用。” [Ulrich Drepper,"How To Write Shared Libraries"]。
如果您在系统上的静态glibc上运行nm
(如果有的话),libc.a
,您会注意到pthread_mutex_lock
等功能被标记为弱。在动态版本libc.so.<whatetever>
中,函数未标记为弱。
注意:您应该使用nm -D
或nm --dynamic
来查看共享库中的符号。 nm
不会在已剥离的共享库上生成任何内容。如果是,则查看调试符号,而不是动态符号。
答案 1 :(得分:4)
见SO answer。根据是否使用动态链接或静态链接,可以使用多种技术在允许链接程序的多个库中定义相同的符号。
符号插入。动态链接时,如果在多个库中定义了符号,则链接器将使用它找到的第一个版本(除非符号是内部的,隐藏的或受保护的;请参阅this blog article以获取该描述)
弱对象。当静态链接时,如果链接器找到两个同名的符号,并且一个是“弱”引用,则链接器将使用非弱引用。
符号版本控制也可能起作用。
几乎在所有情况下,程序都动态链接到libc。
您可以使用ldd:
查看将加载库的顺序$ ldd simple_pthread
linux-vdso.so.1 => (0x00007fffaddff000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007fa13a474000)
libc.so.6 => /lib64/libc.so.6 (0x00007fa13a0e0000)
/lib64/ld-linux-x86-64.so.2 (0x00007fa13a6a0000)
在这里你可以看到libpthread在链接顺序中位于libc之前。这几乎总是如此; libc始终使用默认编译器选项进行最后链接。
因此,与libpthread链接的程序将使用这些符号的pthread版本,因为它们首先在链接顺序中遇到。
如果您仍然不确定,使用设置为“bindings”的环境变量LD_DEBUG启动程序将显示正在发生的实际符号绑定。
如果您使用静态链接,则会链接libc.a而不是libc.so.您可以使用'nm'列出符号的详细信息。弱符号的类型为'W'或'w'。
(感谢@Kaz指出弱符号不影响动态链接)。