gpt4 book ai didi

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

转载 作者:IT王子 更新时间:2023-10-29 00:50:43 42 4
gpt4 key购买 nike

answer建议 -pthread 优于 -lpthread 因为预定义宏。

根据经验,-pthread 只给我一个额外的宏:#define _REENTRANT 1并且它似乎还强制将 libpthread.so.0 作为动态链接时依赖项。

当我使用 -lpthread 进行编译时,只有在我实际调用任何 pthread 函数时才会添加该依赖项。

这对我来说更好,因为这样我就不必在我的构建脚本中以不同方式对待多线程程序。

所以我的问题是,-pthread-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而不是 -lpthread可能已经过时了大约十年半(就 glibc 而言)。在现代 glibc 中,切换到线程完全是动态的,这取决于是否链接了 pthreads 库。 glibc 头文件中的任何内容都不会根据 _REENTRANT 是否改变其行为。已定义。

作为动态切换的一个例子,考虑FILE *溪流。流上的某些操作正在锁定,例如 putc .无论您是否正在编译单线程程序,它都会调用相同的 putc功能;它不会被预处理器重新路由到“pthread-aware”putc .发生的事情是什么都不做的 stub 函数用于完成锁定和解锁的 Action 。当链接线程库时,这些函数会被实际函数覆盖。



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

看到了吗? :)

关于c - -pthread、-lpthread 和最小的动态链接时间依赖性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41267121/

42 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com