设为首页 加入收藏

TOP

Linux程序链接时-lpthread对程序正确性的影响(二)
2015-02-02 14:16:18 来源: 作者: 【 】 浏览:24
Tags:Linux 程序 链接 -lpthread 正确性 影响
中的。


条件变量要更复杂一些。
?
$ 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中的符号。
一切都符合预期。我猜是因为@@的效果。


首页 上一页 1 2 下一页 尾页 2/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇浅析C#中的泛型 下一篇Calabash+Gearman实现多手机同步..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: