Какой код можно назвать «повторно входящим»? - PullRequest
25 голосов
/ 16 февраля 2010

Может ли кто-нибудь сказать мне, какой код можно назвать «повторно входящим» кодом?

Я сталкивался с этим словом при чтении операционной системы реального времени.Какие дисциплины должны соблюдаться для того, чтобы код был «входящим» кодом?

Ответы [ 9 ]

41 голосов
/ 16 февраля 2010

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

В большинстве случаев "действующие лица" являются потоками одного и того же процесса, но понятия безопасности потоков и повторного входа немного отличаются: не каждый потокобезопасный блок является повторно входящим, но каждый повторно входящий блок является потокобезопасным. То есть повторный вход является более сильным свойством, чем безопасность потока. Вот хороший пример от Раймонда Чена о том, как блок кода может быть поточно-ориентированным, но не входящим.

Существует особый случай, когда код является рекурсивным: тот же самый актер вызывает код до того, как его собственный вызов завершен, как отмечает Марк Гравелл. Все правильные рекурсивные блоки являются реентерабельными; конечно, не каждый повторяющийся блок является рекурсивным.

10 голосов
/ 16 февраля 2010

В ответе Джона Феминеллы говорится:

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

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

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

Ни один вызов не должен быть в состоянии обнаружить «присутствие» другого.

9 голосов
/ 16 февраля 2010

Практически любой вид рекурсивного кода может быть классифицирован как реентерабельный (т. Е. Вы можете перезвонить в тот же метод, не завершив его), но он используется , в частности , когда речь идет о блокировках, мьютексах, семафорах и т. д. Например, блокировка является повторной, если если у вас есть блокировка , вы можете снова успешно «заблокировать» код (т. е. не блокировать себя самостоятельно) - например:

public void AddIfNecessary(string s) {
    lock(syncObj) {
        if(!Contains(s)) Add(s);
    }
}

public void Add(string s) {
    lock(syncObj) {
        list.Add(s);
    }
}

public bool Contains(string s) {
    lock(syncObj) {
        return list.Contains(s);
    }
}

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

3 голосов
/ 05 ноября 2013

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

1 голос
/ 21 марта 2014

Код, который может вызываться различными потоками, работающими параллельно. Итак, код:

  1. может иметь локальных переменных (размещенных в стеке каждого потока)
  2. должно иметь защищенных глобальных и статических переменных, так как потоки будут делиться ими, и здесь будет условие гонки.
1 голос
/ 16 февраля 2010

Может ли другой поток вызвать код, пока первый поток находится в середине его выполнения? Если код уступает функции обратного вызова, может ли сама функция обратного вызова вызвать код до завершения первого выполнения?

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

0 голосов
/ 24 ноября 2016

Проще говоря, повторно входящий код - это код, который может использоваться несколькими процессами.

Это возможно при соблюдении следующих условий:

  1. Не должно иметь глобальных и статических данных.
  2. Он не должен изменять свой собственный код.
  3. Он не должен вызывать другую возвращающуюся функцию или сегмент кода.

Итак, код, соответствующий этим условиям, можно назвать кодом повторного входа.

0 голосов
/ 31 мая 2016

Пример без повторного входа

class Test {
    int count;

    // Here method1() is not reentrant
    int method1()
    {
        return count + 1;
    }
}

Пример повторного входа

class Test {
    int count;

    // Here method1() is reentrant
    int method1(int count)
    {
        return count + 1;
    }
}
0 голосов
/ 08 июня 2012

Компьютерная программа называется реентерабельной, если ее можно прервать в середине выполнения, а затем безопасно вызвать снова, прежде чем ее предыдущие вызовы завершат выполнение. Прерывание может быть вызвано внутренним действием, таким как переход или вызов, или внешним действием, таким как аппаратное прерывание или сигнал. После завершения повторного вызова предыдущие вызовы возобновят правильное выполнение.

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