中的。
条件变量要更复杂一些。 ? $ nm /lib64/libc.so.6 | grep pthread_cond_init 00000000000f7ff0 t __pthread_cond_init 0000000000127c30 t __pthread_cond_init_2_0 00000000000f7ff0 T pthread_cond_init@@GLIBC_2.3.2 0000000000127c30 T pthread_cond_init@GLIBC_2.2.5 ? libc中提供了两个版本的条件变量的实现,@@后面是版本号。一个是GLIBC_2.2.5,一个是GLIBC_2.3.2。其中GLIBC_2.3.2是基于NPTL的。由于它定义了多个版本的实现,所以就应该有一个默认实现。带@@的就是默认实现。 ? 我没看出来libpthread和libc中的cond vars的实现有什么区别。
另外我又重复了一下网上那篇帖子中的实验
$ cat test.c #include ? static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; ? int func(){ ? pthread_mutex_lock(&mutex); ? pthread_mutex_unlock(&mutex); ? return 0; } ? $ cat main.c ? extern int func(); ? int main(){ ? func(); ? return 0; } ? $ gcc -shared -fPIC -o libt1.so test.c -g $ gcc -o m main.c -g -lt1 -L. -Wl,-rpath,. ? 两次编译我都故意没有加-pthread,然后发现pthread_mutex_lock确实使用的是空实现。 但是动态库的符号是这样写的: $ nm libt1.so? |grep pthread U pthread_mutex_lock@@GLIBC_2.2.5 U pthread_mutex_unlock@@GLIBC_2.2.5 ? $ readelf -a libt1.so | grep pthread 000000200888? 000500000007 R_X86_64_JUMP_SLO 0000000000000000 pthread_mutex_lock + 0 000000200890? 000600000007 R_X86_64_JUMP_SLO 0000000000000000 pthread_mutex_unlock + 0 ? ? ? 5: 0000000000000000? ? 0 FUNC? ? GLOBAL DEFAULT? UND pthread_mutex_lock@GLIBC_2.2.5 (2) ? ? ? 6: 0000000000000000? ? 0 FUNC? ? GLOBAL DEFAULT? UND pthread_mutex_unlock@GLIBC_2.2.5 (2) ? ? 58: 0000000000000000? ? 0 FUNC? ? GLOBAL DEFAULT? UND pthread_mutex_lock@@GLIBC ? ? 60: 0000000000000000? ? 0 FUNC? ? GLOBAL DEFAULT? UND pthread_mutex_unlock@@GLI ? ? 当我修改主程序的链接参数后: $ gcc -o m main.c -g -lt1 -L. -Wl,-rpath,. -pthread $ ldd ./m ? ? linux-vdso.so.1 =>? (0x00007fff710bf000) ? ? libt1.so => ./libt1.so (0x00007fc37216f000) ? ? libpthread.so.0 => /lib64/libpthread.so.0 (0x00007fc371f47000) ? ? libc.so.6 => /lib64/libc.so.6 (0x00007fc371bb3000) ? ? /lib64/ld-linux-x86-64.so.2 (0x00007fc372371000) 由于在它启动的时候,就已经链接到了pthread,所以也就没有问题。它会使用pthread的实现,无需修改so的链接参数。 ? 然后我又试了一下dlopen。 我把main函数改成这样 #include #include ? ? int main(){ ? int (*func)(); ? void* handle =dlopen("./libt1.so", RTLD_NOW); ? if (!handle) { ? ? ? ? fprintf(stderr, "%s\n", dlerror()); ? ? ? ? return -1; ? ? } ? func = (int (*)()) dlsym(handle, "func"); ? func(); ? return 0; } ? $gcc -o m main.c -g -pthread -ldl 经gdb调试,依然使用的是/lib64/libpthread.so.0中的符号。 一切都符合预期。我猜是因为@@的效果。
|