编译多线程程序时使用的 gcc -pthread和 gcc -lpthread有什么区别?
gcc -pthread
gcc -lpthread
-pthread告诉编译器在 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 库被链接——预定义的宏不会被定义。
-lpthread
底线: 您应该使用 -pthread选项。
注意: 在 GCC 文档中,-pthread选项被记录为一个特定于平台的选项,因此它可能并不总是可用。但是,它可以在 GCC 文档没有明确列出它的平台上使用(比如 i386和 x86-64)——如果可用,应该使用它。
还要注意的是,GCC 还使用了其他类似的选项,例如 -pthreads(在 Solaris 2上作为 -pthread的同义词列出)和 -mthread(在 i386和 x86-64 Windows 上支持特定于 MinGW 的线程)。我的理解是,海湾合作委员会正试图转向使用 -pthread统一前进。
-pthreads
-mthread
-pthread通过 pthread 库添加对多线程的支持。此选项同时设置预处理器和链接器(man gcc)的标志。
man gcc
同时
-lpthread在链接时存在,在预处理时不会受到影响。
有一个被接受的答案,但是,在我看来,它并没有提供足够的背景和洞察力,因此这个额外的答案。
-lpthread是一个不再存在的问题的解决方案(从2005年开始)。
在过去,有一些 Pthread API的专有实现与 POSIX 不兼容,比如 LinuxThreads。POSIX 标准只是说,如果想要 POSIX 兼容的行为,那么必须链接到 -lpthread,而链接到 Pthread API 的 POSIX 兼容的实现,如果有 < em > < strong > 倍数 的实现就需要这样的链接。
在现代操作系统中没有多个 Pthread API 实现。这就是为什么 -lpthread不再有任何作用。
像 gcc和 clang这样的编译器(可能还有所有与 Linux 兼容的编译器)使用 -pthread命令行选项编译和链接符合 POSIX 的多线程应用程序的 要求,这是必须使用的。
gcc
clang
编译器的文档是最终的权威来源,任何分歧的第三方文档是相当无关紧要的。
在编译时,-pthread选项显示 Pthread API 被请求(可以有多个线程 API,例如 Solaris Threads) ,并定义平台特定的宏(Solaris 上的 Linux 上的 _REENTRANT、 _MT)。
_REENTRANT
_MT
在链接时,-pthread链接到实现符合 POSIX 的 Pthread API 行为的所需库(如果有的话)中。
以上说明了为什么 -lpthread既不必要也不充分。
GNU libc 2.34:
新的应用程序不需要链接到 -lpthread,-ldl,-lutil,-lanl了。为了向后兼容,提供了空静态存档 libpthread.a、 libdl.a、 libutil.a、 libanl.a,以便连接器选项继续工作。已经链接到 glibc 2.33或更早版本的应用程序继续加载相应的共享对象(现在是空的)。
-ldl
-lutil
-lanl
libpthread.a
libdl.a
libutil.a
libanl.a