Разъяснение того, как GNU C Library определяет не-входящие функции - PullRequest
0 голосов
/ 06 января 2020

Взято из: https://www.gnu.org/software/libc/manual/html_node/Nonreentrancy.html

Например, предположим, что обработчик сигнала использует gethostbyname. Эта функция возвращает свое значение в объекте stati c, каждый раз используя один и тот же объект. Если случится, что сигнал поступит во время вызова gethostbyname или даже после него (пока программа все еще использует это значение), он изменит значение, запрошенное программой.

Я не могу Посмотрите, как приведенный выше сценарий не реентерабельный Мне кажется, что gethostbyname является (только для чтения) геттерной функцией, которая просто читает из памяти (в отличие от модификации памяти). Почему gethostbyname не возвращается?

1 Ответ

1 голос
/ 07 января 2020

Как говорится в слове, повторное включение - это способность функции вызываться снова, когда она вызывается в другом потоке. Сценарий, который вы предлагаете, является точным местом, в котором осуществляется повторный вход. Функция asume имеет некоторую static или глобальную переменную (как и функция gethostbyname(3)). Поскольку буфер возврата структуры записывается одним, другой вызов может перезаписать ее, чтобы полностью уничтожить первую запись. Когда в исполнении экземпляр функции (прерванный, а не прерывающий) снова получает управление, все его данные были перезаписаны прерывающим и уничтожили его.

A Распространенным решением для решения этой проблемы с прерываниями является отключение прерываний во время выполнения функции. Таким образом, он не прерывается новым вызовом самого себя.

Если два потока вызывают один и тот же фрагмент кода, и все параметры и локальные переменные хранятся в стеке, каждый поток имеет копию его собственные данные, поэтому нет проблем в вызове обоих одновременно, поскольку данные, к которым они обращаются, находятся в разных стеках. Этого не произойдет с static переменными, такими как локальная область, область модуля компиляции или глобальная область (подумайте, что проблема возникает при вызове одного и того же фрагмента кода, поэтому везде, где один вызов имеет доступ, другой также имеет)

Stati c данные, такие как буферы (посмотрите на буферизованные пакеты stdio) et c. в общем, подпрограммы не будут реентерабельными.

...