使用 -pthread 如何不违反 ODR 规则?

Fla*_*ire 5 c c++ pthreads one-definition-rule

我最近通过 CFFI 进行了 Python 扩展/包构建,它使用pthread_atfork(和 pthread 互斥锁)但不与 pthread 链接,即既不指定-pthread也不指定-lpthread,因此在具有由 libpthread 链接的静态部分的系统上失败由于缺少符号,链接脚本(而不是纯粹的共享库)。

在考虑正确的修复时,我在编译时偶然发现了-pthread 和 -lpthread 之间差异。因此,-pthread在编译和链接步骤中使用不仅放置-lpthread在正确的位置(在上述设置中至关重要),而且还定义了改变函数定义的预处理器符号。

(第三方)函数的一个例子是boost::datetime::c_time::localtime(...)调用localtime_rstd::localtime

这不是(很可能)违反 ODR 的来源吗?因此,例如编译一个根本不使用线程的简单静态库,-pthread并将其链接到一个使用线程的二进制文件中,因此正在使用-pthread将导致此类函数的不同定义并且是 UB(/IB?)?

然而从我/usr/include/features.h看来

   _REENTRANT, _THREAD_SAFE
      Obsolete; equivalent to _POSIX_C_SOURCE=199506L.
Run Code Online (Sandbox Code Playgroud)

所以问题:

  1. 是否存在/是否由于 ODR 违规-pthread,如果是,为什么(不是避免/故意/疏忽)?
  2. 这些定义不再相关了吗?所以-pthread现在相当于-lpthread(保存展示位置)?
  3. 应该使用什么来构建 Python 的 CFFI 扩展?使用-pthread是困难的,因为编译器相关的命名(-pthread, -pthreads, -mthreads...)

Ctx*_*Ctx 4

在 Linux 上,该标志-pthread实际上-lpthread只是另外将标志传递-D_REENTRANT给 gcc 选项,这现在已经过时了。

另请参阅以下评论features.h

/* Some C libraries once required _REENTRANT and/or _THREAD_SAFE to be
   defined in all multithreaded code.  GNU libc has not required this
   for many years.  We now treat them as compatibility synonyms for
   _POSIX_C_SOURCE=199506L, which is the earliest level of POSIX with
   comprehensive support for multithreaded code.  Using them never
   lowers the selected level of POSIX conformance, only raises it.  */
Run Code Online (Sandbox Code Playgroud)

但是,可能仍然存在 C 标准库实现,这些实现依赖于_REENTRANT编译多线程代码时定义。然而,对于 libc(可能在大多数其他环境中),您可以安全地用于-lpthread编译。