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

2023-11-21

This 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。所发生的情况是,不执行任何操作的存根函数用于完成锁定和解锁的动作。当链接线程库时,这些函数将被覆盖为真实函数。



我只是粗略地做了一个grep通过 glibc 安装的包含文件树。在features.h, _REENTRANT causes __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.

See? :)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

-pthread、-lpthread 和最小动态链接时依赖性 的相关文章

随机推荐