【问题标题】:In-depth explanation for why we need '-pthread' in Linker option for gcc?深入解释为什么我们需要在 gcc 的链接器选项中使用“-pthread”?
【发布时间】:2019-12-28 05:00:06
【问题描述】:

要使用 pthread_create 和其他 POSIX 线程库函数,我们需要这个标志。我们为什么需要这个?

为什么 /usr 中没有像其他函数或其他系统调用的实现一样实现这些函数的代码?

另一个问题:此外,如果没有此标志,则会出现以下输出:ERROR

我的问题是,为什么我们会在编译时收到这些错误(未定义的引用...)? gcc 应该生成可执行文件,并且在运行时,它应该尝试找到这些符号,对吗? (动态链接)

注意:这些符号(pthread_create、pthread_join)是外部符号(在 preproc 中使用 -E gcc 标志检查)。这与运行时加载的符号不同吗?

【问题讨论】:

  • undefined reference 链接器错误由于缺少链接 pthread 库。这可以通过执行-lpthread 来解决任何其他要链接的库。指定-pthread 意味着-lpthread
  • @kalyum 确实如此,但我一直在寻找关于我们为什么需要 -pthread 的深入解释。为什么链接器不能自动找到 pthread_create() 的代码所在的动态库
  • 链接器为什么不自动找到动态库”除了 C 库之外,链接器不知道任何库的位置。这不仅与 libpthead 有关,还与所有其他库有关。

标签: c gcc linker operating-system dynamic-linking


【解决方案1】:

您的大致笔划是正确的,我会尝试分解您问题的每个部分并为您指出正确的方向。

要使用 pthread_create 和其他 POSIX 线程库函数,我们需要这个标志。我们为什么需要这个?

pthreads 不是作为 gcc 内置程序或作为“标准”libc 的一部分实现的,这意味着外部库必须实现它们。由于需要外部库,因此需要使用 -pthread 标志通知链接器有关该外部库的信息。

为什么 /usr 中没有像其他函数或其他系统调用的实现一样实现这些函数的代码?

绝对是,pthread API 是在 libpthread 中实现的,您几乎可以肯定会在它的共享 (libpthread.so)、静态 (libpthread.a) 和特定版本 (libpthread-X.YY.so) 中找到它/usr/lib 文件夹中的表单。

此外,如果没有此标志,则会出现以下输出:ERROR

这是链接器,告诉您您尚未指定要使用的 pthread 实现。仅仅因为 glibc 提供了一个实现并不意味着这就是您打算使用的实现。链接器不是读心器,它需要在编译时被告知您要链接到哪些特定库。

我的问题是,为什么我们会在编译时收到这些错误(未定义的引用...)? gcc 应该生成可执行文件,并且在运行时,它应该尝试找到这些符号,对吗? (动态链接)

再一次,链接器需要在编译时知道具体它将在运行时查找什么库。定义相同符号的两个库的 ABI 可能不同(并且可能不会相同,除非专门设计用于)。这意味着即使您的动态链接代码不会携带库的静态链接副本,代码的二进制结构仍然取决于库依赖关系。因此,这些信息必须在编译时就知道。

注意:这些符号(pthread_create、pthread_join)是外部符号(在 preproc 中使用 -E gcc 标志检查)。这与运行时加载的符号不同吗?

不,extern 只是通知编译器不会在给定的编译单元中定义符号。如果这没有意义,它基本上意味着,“该符号是在另一个文件中定义的,我只是在这里使用它”。

【讨论】:

  • 非常感谢您的深入解释。我能够理解为什么对于某些函数,我们需要显式地提供动态链接库的名称。
猜你喜欢
  • 2014-11-14
  • 2018-07-28
  • 2018-10-29
  • 1970-01-01
  • 2022-01-21
  • 1970-01-01
  • 1970-01-01
  • 2018-02-23
  • 1970-01-01
相关资源
最近更新 更多