Что такое флаг _REENTRANT? - PullRequest
       20

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

22 голосов
/ 08 апреля 2010

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

gcc -lpthread -D_REENTRANT -o someprogram someprogram.c

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

Ответы [ 5 ]

21 голосов
/ 08 апреля 2010

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

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

4 голосов
/ 22 октября 2018

Выдержка из руководства 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 голосов
/ 18 апреля 2018

JayM ответил:

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

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

Поскольку мы с О.П. интересовались этим вопросом, я решил опубликовать ответ. :) Следующие вещи происходят с _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 равно , а не # определено. Мое дикое предположение состоит в том, что это просто историческая ошибка, которую никто не удосужился пройти и очистить.

Конечно, мои наблюдения на этих двух системах могут не обобщаться на все системы, с которыми ваш код может когда-либо сталкиваться. Вы определенно должны все же передавать -pthread компилятору (или, что менее хорошо, но нормально, -lpthread -D_REENTRANT), когда вашей программе требуются pthreads.

1 голос
/ 08 апреля 2010

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

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

0 голосов
/ 22 января 2019

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...