Подтвердить что ты не робот

Что такое флаг _REENTRANT?

который компилирует многопоточную программу, мы используем gcc, как показано ниже:

gcc -lpthread -D_REENTRANT -o someprogram someprogram.c

что именно делает флаг -D_REENTRANT здесь?

4b9b3361

Ответ 1

Определение _REENTRANT заставляет компилятор использовать поточно-безопасные (т.е. повторные) версии нескольких функций в библиотеке C.

Вы можете искать файлы заголовков, чтобы узнать, что произойдет, когда они будут определены.

Ответ 2

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.

Ответ 3

Это взято из руководства 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 также не имеет никакого эффекта.

Ответ 4

Он просто определил _REENTRANT для препроцессора. Где-то в связанном коде вы, вероятно, найдете #ifdef _REENTRANT или #if defined(_REENTRANT), по крайней мере, в нескольких местах.

Также обратите внимание, что имя "_REENTRANT: находится в пространстве имен исполнителей (любое имя, начинающееся с подчеркивания, за которым следует другое подчеркивание или заглавная буква), поэтому определение означает, что вы вышли за пределы того, что определяет стандарт (при как минимум, на C или С++).

Ответ 5

В многопоточных программах вы указываете компилятору, что вам нужна эта функция, определяя макрос _REENTRANT перед любыми строками #include в вашей программе. Это делает три вещи, и делает их настолько элегантно, что обычно вам даже не нужно знать, что было сделано:

  1. Некоторые функции получают прототипы для безопасного повторного входа. Обычно это одно и то же имя функции, но с добавлением _r, так что, например, gethostbyname изменяется на gethostbyname_r.
  2. Некоторые функции stdio.h, которые обычно реализуются как макросы, становятся правильными повторно входящими безопасными функциями.
  3. Переменная errno из errno.h изменена на вызов функции, которая может определять действительное значение errno многопоточным безопасным способом.

Взято с начала программирования Linux