我最近通过 CFFI 构建了一个 Python 扩展/包构建,它使用pthread_atfork
(和 pthread 互斥锁(但不链接到 pthread,即既不指定-pthread
也不指定-lpthread
,因此在具有静态部分的系统上失败,该静态部分由于缺少符号而由 libpthread 链接脚本(而不是纯粹的共享库(链接。
在考虑正确的修复程序时,我在编译时偶然发现了 -pthread 和 -lpthread 之间的区别。因此,在编译和链接步骤中使用-pthread
不仅可以将-lpthread
放置在正确的位置(在上述设置中至关重要(,还可以定义更改函数定义的预处理器符号。
(第三方(函数的一个示例是boost::datetime::c_time::localtime(...)
调用localtime_r
或std::localtime
。
这不是(很可能(违反 ODR 的来源吗?因此,例如,编译一个简单的静态库,根本不使用线程而不-pthread
并将其链接到一个确实使用线程的二进制文件,因此正在使用-pthread
将导致对此类函数的不同定义并成为 UB(/IB?
然而,从我/usr/include/features.h
我看到
_REENTRANT, _THREAD_SAFE
Obsolete; equivalent to _POSIX_C_SOURCE=199506L.
所以问题:
是否- /是否由于
-pthread
而违反ODR,如果是,为什么(是 它不是避免/故意/疏忽(? - 这些定义是否不再相关?那么
-pthread
现在等同于-lpthread
(保存位置(? - 应该使用什么来构建Python的CFFI扩展?由于编译器依赖命名(
-pthread, -pthreads, -mthreads
,...(,使用-pthread
是困难的。
在 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. */
但是,可能仍然存在 C 标准库实现,这些实现依赖于编译多线程代码时要定义的_REENTRANT
。但是,对于 libc(可能在大多数其他环境中(,您可以安全地使用-lpthread
进行编译。