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

PSkocik:

这个答案建议-pthread比使用-lpthread预定义宏更好

从经验上讲-pthread只给我一个额外的宏:#define _REENTRANT 1而且它似乎也被强制libpthread.so.0作为动态链接时依赖项。

当我使用编译时-lpthread,仅当我实际调用任何pthread函数时,才会添加该依赖项

这对我来说最好,因为这样我就不必在构建脚本中对多线程程序进行不同的处理。

所以我的问题是,-pthreadvs -lpthread还有什么,可以使用use -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而不是GCC的想法-lpthread可能已经过了十五年了(关于glibc)。在现代glibc中,基于pthreads库是否链接,切换到线程是完全动态的。glibc标头中的任何内容都_REENTRANT不会根据是否定义而改变其行为

作为动态切换的示例,请考虑FILE *流。流上的某些操作已锁定,例如putc无论您是否在编译单线程程序,它都将调用同一putc函数。预处理程序不会将它重新路由到“ pthread-aware” putc发生的事情是什么都不做的存根函数用于锁定和解锁的动作。当链接线程库时,这些函数将被覆盖为真实函数。



我只是粗略地grep浏览了glibc安装的include文件树。在中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.

看到?:)

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章