加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > Linux > 正文

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

发布时间:2020-12-13 23:54:36 所属栏目:Linux 来源:网络整理
导读:这个 answer建议-pthread比-lpthread更可取,因为预定义的宏. 根据经验,-pthread只给我一个额外的宏:#define _REENTRANT 1 它似乎也强制libpthread.so.0作为动态链接时依赖. 当我使用-lpthread进行编译时,只有在我实际调用任何pthread函数时才会添加该依赖项
这个 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.

看到?

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读