【发布时间】:2020-06-25 20:38:21
【问题描述】:
编译多线程程序时使用的gcc -pthread和gcc -lpthread有什么区别?
【问题讨论】:
标签: multithreading gcc thread-safety pthreads compiler-flags
编译多线程程序时使用的gcc -pthread和gcc -lpthread有什么区别?
【问题讨论】:
标签: multithreading gcc thread-safety pthreads compiler-flags
-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。
【讨论】:
-lpthread 就足以获得整个 POSIX 线程库。
-lpthread 确实 获得整个 POSIX 线程库。
-lpthread 链接应该足以获得完整的 pthread 支持。不需要其他编译标志。
-lpthread 链接,则 pthread 必须工作。但是,gcc 文档表明这可能不足以获得 pthreads 支持,这是我通过之前的 cmets 提出的观点。如果您不提供-lpthread 或其他一些随机的专有选项,我根本不关心会发生什么。 POSIX 仅指定 -lpthread 来保证 pthreads,而 gcc 似乎还不够。
-pthread 通过 pthreads 库添加对多线程的支持。此选项为预处理器和链接器设置标志 (man gcc)。
同时
-lpthread 在链接时存在,在预处理时不会有影响。
【讨论】:
有一个公认的答案,但是,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 或更早版本链接的应用程序继续加载相应的共享对象(现在为空)。
【讨论】: