什么是_REENTRANT标志?

编译multithreading程序我们使用gcc如下:

gcc -lpthread -D_REENTRANT -o someprogram someprogram.c 

标志-D_REENTRANT到底在做什么?

定义_REENTRANT会导致编译器在C库中使用多个函数的线程安全(即可重入)版本。

您可以搜索头文件以查看定义时发生的情况。

JayM回复说:

定义_REENTRANT会导致编译器在C库中使用多个函数的线程安全(即可重入)版本。

您可以搜索头文件以查看定义时发生的情况。

由于OP和我都对这个问题感兴趣,我决定实际发布答案。 :)在Mac OS X 10.11.6上使用_REENTRANT会发生以下情况:

  • 获得lgammaf_rlgamma_rlgammal_r

在Linux(Red Hat Enterprise Server 5.10)上,我看到以下更改:

  • 获得POSIX 1995函数getlogin_r的声明。

所以似乎_REENTRANT主要是一种无操作, _REENTRANT 。 它可能曾经宣布了许多新function,例如strtok_r ; 但是现在这些function大多是由几十年前的标准(C99,POSIX 95, POSIX.1-2001等)强制执行的,所以它们总是被启用。

我不知道为什么我检查的两个系统都避免声明lgamma_r resp。 当_REENTRANT 不是 #defined时, getlogin_r 。 我的猜测是,这只是历史上的残余,没有人会费心去清理。

当然,我对这两个系统的观察可能不会推广到您的代码可能遇到的所有系统。 当你的程序需要pthread时,你绝对应该将-pthread传递给编译器(或者,不太好但是没问题, -lpthread -D_REENTRANT )。

它只是为预处理器定义了_REENTRANT。 在相关代码的某处,您可能会在至少几个地方找到#ifdef _REENTRANT#if defined(_REENTRANT)

另请注意,名称“_REENTRANT:在实现者的名称空间中(任何以下划线开头,后跟另一个下划线或大写字母的名称),因此定义它意味着您已超出标准定义的范围(至少C或C ++标准)。

这取自libc 8.2手册 :

宏:_REENTRANT
宏:_THREAD_SAFE

这些宏已经过时了。 它们与使用值199506L定义_POSIX_C_SOURCE具有相同的效果。

一些非常古老的C库需要为基本function(例如getchar)定义其中一个宏以确保线程安全。

我们建议您在新程序中使用_GNU_SOURCE。 如果未指定GCC的’-ansi’选项或其他一致性选项(如-std = c99),并且未明确定义任何这些宏,则效果与将_DEFAULT_SOURCE定义为1的效果相同。

定义要素测试宏以请求更大类的要素时,另外为这些要素的子集定义要素测试宏是无害的。 例如,如果定义_POSIX_C_SOURCE,则定义_POSIX_SOURCE也无效。 同样,如果定义_GNU_SOURCE,则定义_POSIX_SOURCE或_POSIX_C_SOURCE也无效。