链接“-lpthread”是否会改变应用程序行为? (Linux,Glibc)

我有一个问题:如果我们有一个不使用线程的应用程序,我们可以通过两种方式来链接它:

1)像往常一样链接,没有-lpthread-ldl

2)添加到链接两个库:libpthread和libdl。

例如

 $ cat ac int main(){printf("Hehe");} $ gcc ac -w -oa $ gcc ac -w -o a1 -ldl -lpthread 

默认情况下,两个库都是dynamic链接的:

 $ ldd a linux-gate.so.1 libc.so.6 /lib/ld-linux.so.2 $ ldd a1 linux-gate.so.1 libdl.so.2 libpthread.so.0 libc.so.6 /lib/ld-linux.so.2 

版本a和版本a1之间会有多大的区别? 什么将以不同的方式在应用程序本身和int glibc中工作? pthreads的链接是否会将线程不安全的内容从线程安全的algorithm改变为线程安全的algorithm?

例如

 $ strace ./a 2>&1 |wc -l 73 $ strace ./a1 2>&1 |wc -l 103 

在a1跟踪中,加载了两个额外的库,调用了一些更多的mprotect ,并添加了以下部分:

  set_tid_address; set_robust_list; rt_sigaction x 2; rt_sigprocmask; getrlimit; uname 

glibc本身包含许多pthread函数的存根代码。 这些glibc pthread函数什么都不做。 但是,当程序与libpthread链接时,那些存根被替换为真正的pthread锁定函数。

这是为了在需要线程安全但不自己使用线程的库中使用。 这些库可以使用pthread锁,但是这些锁实际上不会发生,直到链接到libpthread的程序或库被加载。