编译时 -pthread 和 -lpthread 之间的区别
Posted
技术标签:
【中文标题】编译时 -pthread 和 -lpthread 之间的区别【英文标题】:Difference between -pthread and -lpthread while compiling 【发布时间】:2014-06-08 16:10:09 【问题描述】:编译多线程程序时使用的gcc -pthread
和gcc -lpthread
有什么区别?
【问题讨论】:
Significance of -pthread flag when compiling的可能重复 【参考方案1】:-pthread
告诉编译器链接到 pthread 库以及配置线程的编译。
例如,以下显示了在我的 Ubuntu 机器上安装的 GCC 包上使用 -pthread
选项时定义的宏:
$ gcc -pthread -E -dM test.c > dm.pthread.txt
$ gcc -E -dM test.c > dm.nopthread.txt
$ diff dm.pthread.txt dm.nopthread.txt
152d151
< #define _REENTRANT 1
208d206
< #define __USE_REENTRANT 1
使用 -lpthread
选项只会导致 pthread 库被链接 - 未定义预定义的宏。
底线:您应该使用-pthread
选项。
注意:-pthread
选项在 GCC 文档中被记录为特定于平台的选项,因此它可能并不总是可用。但是,它可在 GCC 文档未明确列出的平台上使用(例如 i386 和 x86-64) - 您应该在可用时使用它。
另请注意,GCC 使用了其他类似的选项,例如 -pthreads
(在 Solaris 2 上列为 -pthread
的同义词)和 -mthread
(用于 i386 和 x86-64 上的 MinGW 特定线程支持视窗)。我的理解是,GCC 正试图继续使用-pthread
。
【讨论】:
这很奇怪,因为它直接与 POSIX 相矛盾。 POSIX 要求通过-lpthread
就足以获得整个 POSIX 线程库。
@FUZxxl 传递 -lpthread
确实 获得整个 POSIX 线程库。
@immibis 不,我的意思是,POSIX 说与-lpthread
链接应该足以获得完整的 pthread 支持。不需要其他编译标志。
@alecov POSIX 规定,如果您配置 POSIX 环境并与 -lpthread
链接,则 pthread 必须工作。但是,gcc 文档表明这可能不足以获得 pthreads 支持,这是我通过之前的 cmets 提出的观点。如果您不提供-lpthread
或其他一些随机的专有选项,我根本不关心会发生什么。 POSIX 仅指定 -lpthread
来保证 pthreads,而 gcc 似乎还不够。【参考方案2】:
有一个公认的答案,但是,IMO,它没有提供足够的背景和洞察力。因此,这个额外的答案。
-lpthread
是一个不再存在的问题的解决方案(自~2005 年以来)。
在过去,Pthreads API 的专有实现不符合 POSIX,例如 LinuxThreads。 POSIX 标准只是说,如果一个人想要符合 POSIX 的行为,那么必须与-lpthread
链接,并且链接是链接符合 POSIX 的 Pthreads API 实现所需的链接,应该有 它的多个实现。
现代操作系统中没有 Pthreads API 的多种实现。这就是为什么-lpthread
不再有任何用途的原因。
像gcc
和clang
这样的编译器(可能还有所有与Linux 兼容的编译器)需要 使用-pthread
命令行选项来编译和链接符合POSIX 的多线程应用程序这是必须使用的。
编译器的文档是最终的权威来源,任何不同的第 3 方文档都是无关紧要的。
在编译时,-pthread
选项表明请求了 Pthread API(可以有多个线程 API,例如 Solaris 线程)并定义特定于平台的宏(_REENTRANT
on Linux、_MT
在 Solaris 上)。
在链接时,-pthread
链接到实现符合 POSIX 标准的 Pthreads API 行为的所需库(如果有)中。
以上说明了为什么-lpthread
既非必要也不充分。
GNU libc 2.34:
新应用程序不再需要与
-lpthread
、-ldl
、-lutil
、-lanl
链接。为了向后兼容,提供了空的静态存档libpthread.a
、libdl.a
、libutil.a
、libanl.a
,以便链接器选项继续工作。与 glibc 2.33 或更早版本链接的应用程序继续加载相应的共享对象(现在为空)。
【讨论】:
【参考方案3】:-pthread
通过 pthreads 库添加对多线程的支持。此选项为预处理器和链接器设置标志 (man gcc
)。
同时
-lpthread
在链接时存在,在预处理时不会受到影响。
【讨论】:
以上是关于编译时 -pthread 和 -lpthread 之间的区别的主要内容,如果未能解决你的问题,请参考以下文章