运维开发网
广告位招商联系QQ:123077622
 
广告位招商联系QQ:123077622

-pthread,-lpthread和最小动态链接时间依赖性

运维开发网 https://www.qedev.com 2020-07-05 14:17 出处:网络
这个 answer建议-pthread比-lpthread更可取,因为预定义的宏. 根据经验,-pthread只给我一个额外的宏:#define _REENTRANT 1它似乎也强制libpthread.so.0作为动态链接时依赖.
这个 answer建议-pthread比-lpthread更可取,因为预定义的宏.

根据经验,-pthread只给我一个额外的宏:#define _REENTRANT 1

它似乎也强制libpthread.so.0作为动态链接时依赖.

当我使用-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.

看到?

扫码领视频副本.gif

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号