который компилирует многопоточную программу, мы используем gcc, как показано ниже:
gcc -lpthread -D_REENTRANT -o someprogram someprogram.c
что именно делает флаг -D_REENTRANT
здесь?
который компилирует многопоточную программу, мы используем gcc, как показано ниже:
gcc -lpthread -D_REENTRANT -o someprogram someprogram.c
что именно делает флаг -D_REENTRANT
здесь?
Определение _REENTRANT заставляет компилятор использовать поточно-безопасные (т.е. повторные) версии нескольких функций в библиотеке C.
Вы можете искать файлы заголовков, чтобы узнать, что произойдет, когда они будут определены.
JayM ответил:
Определение _REENTRANT заставляет компилятор использовать потокобезопасные (т.е. повторно входящие) версии нескольких функций в библиотеке C.
Вы можете искать файлы заголовка, чтобы увидеть, что произойдет, когда он определен.
Так как OP и меня интересовали оба вопроса, я решил опубликовать ответ. :) С _REENTRANT
в Mac OS X 10.11.6 происходят следующие вещи:
<math.h>
получает объявления для lgammaf_r
, lgamma_r
и lgammal_r
.В Linux (Red Hat Enterprise Server 5.10) я вижу следующие изменения:
<unistd.h>
получает объявление для функции POSIX 1995 getlogin_r
. Похоже, в наши дни _REENTRANT
в основном не работает. Когда-то он мог объявить много новых функций, таких как strtok_r
; но в наши дни эти функции в основном соответствуют различным десятилетним стандартам (C99, POSIX 95, POSIX.1-2001 и т.д.), и поэтому они всегда включены.
Я понятия не имею, почему две системы, которые я проверял, избегают объявления lgamma_r
соответственно. getlogin_r
когда _REENTRANT
не является #defined. Мое дикое предположение состоит в том, что это просто историческая ошибка, которую никто никогда не удосужился пережить и очистить.
Конечно, мои наблюдения за этими двумя системами могут не распространяться на все системы, с которыми ваш код когда-либо сталкивался. Вы определенно должны все же передавать -pthread
компилятору (или, что менее хорошо, но хорошо, -lpthread -D_REENTRANT
) всякий раз, когда вашей программе требуются pthreads.
Это взято из руководства libc 8.2:
Макрос: _REENTRANT
Макрос: _THREAD_SAFEЭти макросы устарели. Они имеют тот же эффект, что и определение _POSIX_C_SOURCE со значением 199506L.
Некоторые очень старые библиотеки C требовали, чтобы один из этих макросов был определен для базовой функциональности (например, getchar), чтобы быть потокобезопасным.
Мы рекомендуем использовать _GNU_SOURCE в новых программах. Если вы не указали опцию '-ansi для GCC или другие опции соответствия, такие как -std = c99, и не определили явно ни один из этих макросов, эффект будет таким же, как определение _DEFAULT_SOURCE для 1.
Когда вы определяете макрос тестирования объектов для запроса более широкого класса объектов, безопаснее дополнительно определять макрос тестирования объектов для подмножества этих функций. Например, если вы определяете _POSIX_C_SOURCE, то определение и _POSIX_SOURCE также не имеет никакого эффекта. Аналогично, если вы определяете _GNU_SOURCE, то определение либо _POSIX_SOURCE, либо _POSIX_C_SOURCE также не имеет никакого эффекта.
Он просто определил _REENTRANT для препроцессора. Где-то в связанном коде вы, вероятно, найдете #ifdef _REENTRANT
или #if defined(_REENTRANT)
, по крайней мере, в нескольких местах.
Также обратите внимание, что имя "_REENTRANT: находится в пространстве имен исполнителей (любое имя, начинающееся с подчеркивания, за которым следует другое подчеркивание или заглавная буква), поэтому определение означает, что вы вышли за пределы того, что определяет стандарт (при как минимум, на C или С++).
В многопоточных программах вы указываете компилятору, что вам нужна эта функция, определяя макрос _REENTRANT перед любыми строками #include в вашей программе. Это делает три вещи, и делает их настолько элегантно, что обычно вам даже не нужно знать, что было сделано:
Взято с начала программирования Linux