WikiSort.ru - Не сортированное

ПОИСК ПО САЙТУ | о проекте

Компьютерная программа в целом или её отдельная процедура называется реентера́бельной (от англ. reentrant — повторно входимый), если она разработана таким образом, что одна и та же копия инструкций программы в памяти может быть совместно использована несколькими пользователями или процессами. При этом второй пользователь может вызвать реентерабельный код до того, как с ним завершит работу первый пользователь и это как минимум не должно привести к ошибке, а при корректной реализации не должно вызвать потери вычислений (то есть не должно появиться необходимости выполнять уже выполненные фрагменты кода).

Реентерабельность тесно связана с безопасностью функции в многопоточной среде (thread-safety), тем не менее, это разные понятия. Обеспечение реентерабельности является ключевым моментом при программировании многозадачных систем, в частности, операционных систем.

Для обеспечения реентерабельности необходимо выполнение нескольких условий:

  • никакая часть вызываемого кода не должна модифицироваться;
  • вызываемая процедура не должна сохранять информацию между вызовами;
  • если процедура изменяет какие-либо данные, то они должны быть уникальными для каждого пользователя;
  • процедура не должна возвращать указатели на объекты, общие для разных пользователей.

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

Пример

В следующем фрагменте кода функции f() и g() не являются реентерабельными.

int g_var = 1;

int f ()
{
  g_var = g_var + 2;
  return g_var;
}

int g ()
{
  return f () + 2;
}

Здесь f() зависит от глобальной переменной g_var, поэтому, если два процесса вызывают f() в одно и то же время, результат непредсказуем. Поэтому, f() не реентерабельна. Но и g() не реентерабельна, поскольку она использует нереентерабельную функцию f().

В следующем фрагменте кода функция accum() также не является реентерабельной.

int accum(int b)
{
  static int a = 0; 
  ++a;
  return (a+b);
}

Здесь accum — функция накапливающая значение а, за которое отвечает статическая переменная. Если accum будет вызвана разными процессами, то результат также будет непредсказуем. Как и в предыдущем примере a является общей для всех вызывающих её процессов.

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

#define SQR(x) ((x)*(x))
void func (void)
{
  int x, y;
  x = SQR (y);
}

В этом случае макрос SQR(x) будет работать некорректно, если при каждом обращении к аргументу он изменяется.

Ссылки

Данная страница на сайте WikiSort.ru содержит текст со страницы сайта "Википедия".

Если Вы хотите её отредактировать, то можете сделать это на странице редактирования в Википедии.

Если сделанные Вами правки не будут кем-нибудь удалены, то через несколько дней они появятся на сайте WikiSort.ru .




Текст в блоке "Читать" взят с сайта "Википедия" и доступен по лицензии Creative Commons Attribution-ShareAlike; в отдельных случаях могут действовать дополнительные условия.

Другой контент может иметь иную лицензию. Перед использованием материалов сайта WikiSort.ru внимательно изучите правила лицензирования конкретных элементов наполнения сайта.

2019-2024
WikiSort.ru - проект по пересортировке и дополнению контента Википедии