which compiling a multithreaded program we use gcc like 开发者_Go百科below:
gcc -lpthread -D_REENTRANT -o someprogram someprogram.c
what exactly is the flag -D_REENTRANT
doing over here?
Defining _REENTRANT causes the compiler to use thread safe (i.e. re-entrant) versions of several functions in the C library.
You can search your header files to see what happens when it's defined.
Excerpt from the libc 8.2 manual:
Macro: _REENTRANT
Macro: _THREAD_SAFEThese macros are obsolete. They have the same effect as defining _POSIX_C_SOURCE with the value 199506L.
Some very old C libraries required one of these macros to be defined for basic functionality (e.g. getchar) to be thread-safe.
We recommend you use _GNU_SOURCE in new programs. If you don’t specify the ‘-ansi’ option to GCC, or other conformance options such as -std=c99, and don’t define any of these macros explicitly, the effect is the same as defining _DEFAULT_SOURCE to 1.
When you define a feature test macro to request a larger class of features, it is harmless to define in addition a feature test macro for a subset of those features. For example, if you define _POSIX_C_SOURCE, then defining _POSIX_SOURCE as well has no effect. Likewise, if you define _GNU_SOURCE, then defining either _POSIX_SOURCE or _POSIX_C_SOURCE as well has no effect.
JayM replied:
Defining _REENTRANT causes the compiler to use thread safe (i.e. re-entrant) versions of several functions in the C library.
You can search your header files to see what happens when it's defined.
Since OP and I were both interested in the question, I decided to actually post the answer. :) The following things happen with _REENTRANT
on Mac OS X 10.11.6:
<math.h>
gains declarations forlgammaf_r
,lgamma_r
, andlgammal_r
.
On Linux (Red Hat Enterprise Server 5.10), I see the following changes:
<unistd.h>
gains a declaration for the POSIX 1995 functiongetlogin_r
.
So it seems like _REENTRANT
is mostly a no-op, these days. It might once have declared a lot of new functions, such as strtok_r
; but these days those functions are mostly mandated by various decades-old standards (C99, POSIX 95, POSIX.1-2001, etc.) and so they're just always enabled.
I have no idea why the two systems I checked avoid declaring lgamma_r
resp. getlogin_r
when _REENTRANT
is not #defined. My wild guess is that this is just historical cruft that nobody ever bothered to go through and clean up.
Of course my observations on these two systems might not generalize to all systems your code might ever encounter. You should definitely still pass -pthread
to the compiler (or, less good but okay, -lpthread -D_REENTRANT
) whenever your program requires pthreads.
In multithreaded programs, you tell the compiler that you need this feature by defining the _REENTRANT macro before any #include lines in your program. This does three things, and does them so elegantly that usually you don’t even need to know what was done:
- Some functions get prototypes for a re-entrant safe equivalent. These are normally the same function name, but with _r appended so that, for example, gethostbyname is changed to gethostbyname_r.
- Some stdio.h functions that are normally implemented as macros become proper re-entrant safe functions.
- The variable errno, from errno.h, is changed to call a function, which can determine the real errno value in a multithread safe way.
Taken from Beginning Linux Programming
It simply defined _REENTRANT for the preprocessor. Somewhere in the associated code, you'll probably find #ifdef _REENTRANT
or #if defined(_REENTRANT)
in at least a few places.
Also note that the name "_REENTRANT: is in the implementer's name space (any name starting with an underscore followed by another underscore or a capital letter is), so defining it means you've stepped outside what the standard defines (at least the C or C++ standards).
精彩评论