编译时-pthread和-lpthread之间的差异

Vis*_*j V 99 multithreading gcc pthreads thread-safety compiler-flags

是什么区别gcc -pthreadgcc -lpthread它在编译多线程程序中使用?

Mic*_*urr 108

-pthread 告诉编译器在pthread库中链接以及配置线程的编译.

例如,下面显示了-pthread在我的Ubuntu机器上安装的GCC包上使用该选项时定义的宏:

$ 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
Run Code Online (Sandbox Code Playgroud)

使用该-lpthread选项只会导致pthread库链接 - 预定义的宏不会被定义.

底线:您应该使用该-pthread选项.


注意:该-pthread选项在GCC文档中记录为特定于平台的选项,因此可能并不总是可用.但是,它可以在GCC文档未明确列出的平台上使用(例如i386和x86-64) - 您应该在可用时使用它.

另请注意,GCC已使用其他类似选项,例如-pthreads(-pthread在Solaris 2上列为同义词)和-mthread(对于i386和x86-64 Windows上的MinGW特定线程支持).我的理解是海湾合作委员会正在努力-pthread向前迈进.

  • @immibis不,我的意思是,POSIX说连接`-lpthread`应该足以获得完整的pthreads支持.不需要其他编译标志. (4认同)
  • 这很奇怪,因为它直接与POSIX相矛盾.POSIX要求传递`-lpthread`足以获得整个POSIX线程库. (2认同)
  • @alecov POSIX要求,如果配置POSIX环境并与`-lpthread`链接,则pthread必须起作用。但是,gcc文档建议这可能不足以获得pthreads的支持,这就是我在前面的评论中指出的重点。我根本不在乎如果您不提供`-lpthread`或一些其他随机专有选项会发生什么情况。POSIX只指定`-lpthread`来保证pthread,而gcc似乎还不够。 (2认同)

Max*_*kin 18

有一个公认的答案,但是,IMO,它没有提供足够的背景和洞察力。因此,这个额外的答案。


-lpthread 是一个不再存在的问题的解决方案(自 2005 年以来)。

在过去,有不符合 POSIX 标准的Pthreads API 的专有实现,例如LinuxThreads。POSIX 标准只是说,如果想要符合 POSIX 的行为,那么必须链接-lpthread如果有许多实现,则必须链接,并且链接是链接 Pthreads API 的 POSIX 兼容实现所必需的。

现代操作系统中没有 Pthreads API 的多种实现。这就是为什么-lpthread不再有任何目的的原因。


gccand 之类的编译器clang(可能还有所有与 Linux 兼容的编译器)需要使用-pthread命令行选项来编译和链接符合 POSIX 的多线程应用程序,这是必须使用的。

在编译时,-pthread选项表明请求 Pthread API(可以有多个线程 API,例如 Solaris Threads)并定义特定_REENTRANT平台的宏(在 Linux 上_MT在 Solaris 上)。

在链接时,-pthread实现符合 POSIX 的 Pthreads API 行为的所需库(如果有)中的链接。

上面清楚地说明了为什么-lpthread既不必要也不充分。


GNU libc 2.34:

新应用程序不再需要与-lpthread-ldl-lutil、链接-lanl。为了向后兼容,空静态档案libpthread.alibdl.alibutil.alibanl.a提供,因此链接选项继续工作。已经链接到 glibc 2.33 或更早版本的应用程序继续加载相应的共享对象(现在是空的)。


小智 8

-pthread使用pthreads库添加对多线程的支持.此选项为预处理器和链接器(man gcc)设置标志.

-lpthread 在连接时存在,在预处理时不会产生任何影响.