-pthread,-lpthread和最小动态链接时间依赖性
这个
answer建议-pthread比-lpthread更可取,因为预定义的宏.
根据经验,-pthread只给我一个额外的宏:#define _REENTRANT 1 当我使用-lpthread进行编译时,只有在我实际调用任何pthread函数时才会添加该依赖项. 这对我来说最好,因为那时我不必在构建脚本中以不同方式处理多线程程序. 所以我的问题是,-pthread vs -lpthread还有什么用的,是否可以使用-pthread而不强制表示动态链接时依赖性? 示范: $echo 'int main(){ return 0; }' | c gcc -include pthread.h -x c - -lpthread && ldd a.out | grep pthread $echo 'int main(){ return pthread_self(); }' | c gcc -include pthread.h -x c - -lpthread && ldd a.out | grep pthread libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x0000003000c00000) $echo 'int main(){ return 0; }' | c gcc -include pthread.h -x c - -pthread && ldd a.out | grep pthread libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x0000003000c00000) 解决方法
您应该使用GCC的特殊选项-pthread而不是-lpthread的想法已经过时了大约十五年(相对于glibc而言).在现代的glibc中,根据pthreads库是否链接,切换到线程是完全动态的. glibc头中没有任何内容根据是否定义了_REENTRANT来改变其行为.
作为动态切换的示例,请考虑FILE *流.流上的某些操作是锁定的,就像putc一样.无论您是否编译单线程程序,它都会调用相同的putc函数;它不会被预处理器重新路由到“pthread-aware”putc.发生的事情是,无用的存根函数用于完成锁定和解锁的动作.当链接线程库时,这些函数会被覆盖为真实的函数. 我刚刚通过glibc安装的include文件树做了一个粗略的grep.在features.h中,_REENTRANT导致定义__USE_REENTRANT.反过来,恰好有一件事似乎取决于是否存在__USE_REENTRANT,但是具有并行条件也可以启用它.即,在< unistd.h>中.有这个: #if defined __USE_REENTRANT || defined __USE_POSIX199506 /* Return at most NAME_LEN characters of the login name of the user in NAME. If it cannot be determined or some other error occurred,return the error code. Otherwise return 0. This function is a possible cancellation point and therefore not marked with __THROW. */ extern int getlogin_r (char *__name,size_t __name_len) __nonnull ((1)); #endif 这看起来很可疑,已经过时了;我无法在glibc git repo的master分支中找到它. 哦,看,就在几天前(12月6日),就这一主题做出了承诺: https://sourceware.org/git/?p=glibc.git;a=commit;h=c03073774f915fe7841c2b551fe304544143470f Make _REENTRANT and _THREAD_SAFE aliases for _POSIX_C_SOURCE=199506L. For many years,the only effect of these macros has been to make unistd.h declare getlogin_r. _POSIX_C_SOURCE >= 199506L also causes this function to be declared. However,people who don't carefully read all the headers might be confused into thinking they need to define _REENTRANT for any threaded code (as was indeed the case a long time ago). 其中包括: --- a/posix/unistd.h +++ b/posix/unistd.h @@ -849,7 +849,7 @@ extern int tcsetpgrp (int __fd,__pid_t __pgrp_id) __THROW; This function is a possible cancellation point and therefore not marked with __THROW. */ extern char *getlogin (void); -#if defined __USE_REENTRANT || defined __USE_POSIX199506 +#ifdef __USE_POSIX199506 /* Return at most NAME_LEN characters of the login name of the user in NAME. If it cannot be determined or some other error occurred,return the error code. Otherwise return 0. 看到? (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |