~~~~~~~~~~~~~~~~~~~~ Arc.Ask3.Ru ~~~~~~~~~~~~~~~~~~~~~ 
Номер скриншота №:
✰ 332E1F1F72F551D752B08F4912162366__1706992800 ✰
Заголовок документа оригинал.:
✰ Reentrancy (computing) - Wikipedia ✰
Заголовок документа перевод.:
✰ Реентерабельность (вычисления) — Википедия ✰
Снимок документа находящегося по адресу (URL):
✰ https://en.wikipedia.org/wiki/Reentrant_(subroutine) ✰
Адрес хранения снимка оригинал (URL):
✰ https://arc.ask3.ru/arc/aa/33/66/332e1f1f72f551d752b08f4912162366.html ✰
Адрес хранения снимка перевод (URL):
✰ https://arc.ask3.ru/arc/aa/33/66/332e1f1f72f551d752b08f4912162366__translat.html ✰
Дата и время сохранения документа:
✰ 12.06.2024 04:46:04 (GMT+3, MSK) ✰
Дата и время изменения документа (по данным источника):
✰ 3 February 2024, at 23:40 (UTC). ✰ 

~~~~~~~~~~~~~~~~~~~~~~ Ask3.Ru ~~~~~~~~~~~~~~~~~~~~~~ 
Сервисы Ask3.ru: 
 Архив документов (Снимки документов, в формате HTML, PDF, PNG - подписанные ЭЦП, доказывающие существование документа в момент подписи. Перевод сохраненных документов на русский язык.)https://arc.ask3.ruОтветы на вопросы (Сервис ответов на вопросы, в основном, научной направленности)https://ask3.ru/answer2questionТоварный сопоставитель (Сервис сравнения и выбора товаров) ✰✰
✰ https://ask3.ru/product2collationПартнерыhttps://comrades.ask3.ru


Совет. Чтобы искать на странице, нажмите Ctrl+F или ⌘-F (для MacOS) и введите запрос в поле поиска.
Arc.Ask3.ru: далее начало оригинального документа

Реентерабельность (вычисления) — Википедия Jump to content

Реентерабельность (вычисления)

Из Википедии, бесплатной энциклопедии
(Перенаправлено из Reentrant (подпрограммы) )

Реентерабельность — это концепция программирования, при которой функция или подпрограмма может быть прервана, а затем возобновлена ​​до завершения ее выполнения. Это означает, что функцию можно вызвать еще раз, прежде чем она завершит предыдущее выполнение. Реентерабельный код спроектирован так, чтобы быть безопасным и предсказуемым, когда несколько экземпляров одной и той же функции вызываются одновременно или в быстрой последовательности. Компьютерная программа или подпрограмма называется реентерабельной, если несколько ее вызовов могут безопасно выполняться одновременно на нескольких процессорах или если в однопроцессорной системе ее выполнение может быть прервано и безопасно запущено новое выполнение (ее можно «ввести заново»). "). Прерывание может быть вызвано внутренним действием, таким как переход или вызов, или внешним действием, таким как прерывание или сигнал , в отличие от рекурсии , где новые вызовы могут быть вызваны только внутренним вызовом.

Это определение происходит из мультипрограммных сред, где несколько процессов могут быть активны одновременно и где поток управления может быть прерван прерыванием и передан подпрограмме обслуживания прерываний (ISR) или подпрограмме «обработчика». Любая подпрограмма, используемая обработчиком и которая потенциально могла выполняться в момент срабатывания прерывания, должна быть реентерабельной. Аналогичным образом, код, общий для двух процессоров, осуществляющих доступ к общим данным, должен быть реентерабельным. ​​операционной системы, Часто подпрограммы, доступные через ядро не являются реентерабельными. Следовательно, подпрограммы обслуживания прерываний ограничены в действиях, которые они могут выполнять; например, им обычно ограничен доступ к файловой системе , а иногда даже к выделению памяти .

Повторный вход не является ни необходимым, ни достаточным для обеспечения потокобезопасности в многопоточных средах. Другими словами, реентерабельная подпрограмма может быть потокобезопасной. [1] но это не гарантированно [ нужна цитата ] . И наоборот, потокобезопасный код не обязательно должен быть реентерабельным (примеры см. ниже).

Другие термины, используемые для реентерабельных программ, включают «совместный код». [2] Реентерабельные подпрограммы иногда помечаются в справочных материалах как «безопасные по сигналу». [3] Программы повторного поступления часто [а] «чистые процедуры».

Предыстория [ править ]

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

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

Локальные данные не используются никакими подпрограммами, независимо от того, вводятся они повторно или нет; следовательно, это не влияет на повторный вход. Глобальные данные определяются вне функций и могут быть доступны более чем одной функции либо в форме глобальных переменных (данных, общих для всех функций), либо в виде статических переменных (данных, общих для всех вызовов одной и той же функции). В объектно-ориентированном программировании глобальные данные определяются в области класса и могут быть частными, что делает их доступными только для функций этого класса. Существует также концепция переменных экземпляра , когда переменная класса привязана к экземпляру класса. По этим причинам в объектно-ориентированном программировании это различие обычно зарезервировано для данных, доступных вне класса (общедоступных), и для данных, независимых от экземпляров класса (статических).

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

Правила повторного входа [ править ]

Реентерабельный код не может содержать статические или глобальные непостоянные данные без синхронизации .
Реентерабельные функции могут работать с глобальными данными. Например, процедура обслуживания реентерабельного прерывания может получить часть состояния оборудования для работы (например, буфер чтения последовательного порта), которая не только глобальна, но и нестабильна. разделов кода Тем не менее, типичное использование статических переменных и глобальных данных не рекомендуется, в том смысле, что, за исключением синхронизированных , в этих переменных следует использовать только атомарные инструкции чтения-изменения-записи (это не должно быть возможно для прерывание или сигнал, который должен прийти во время выполнения такой инструкции). Обратите внимание, что в C даже чтение или запись не гарантированно являются атомарными; его можно разделить на несколько операций чтения или записи. [4] Стандарт C и SUSv3 обеспечивают sig_atomic_t для этой цели, хотя и с гарантиями только для простого чтения и записи, а не для увеличения или уменьшения. [5] Более сложные атомарные операции доступны в C11 , который обеспечивает stdatomic.h.
Реентерабельный код не может изменяться без синхронизации.
Операционная система может позволить процессу изменять свой код. Для этого существуют различные причины (например, быстрое копирование графики), но обычно для этого требуется синхронизация, чтобы избежать проблем с повторным входом.

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

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

Повторный вход подпрограммы, которая работает с ресурсами операционной системы или нелокальными данными, зависит от атомарности соответствующих операций. Например, если подпрограмма изменяет 64-битную глобальную переменную на 32-битной машине, операция может быть разделена на две 32-битные операции, и, таким образом, если подпрограмма прерывается во время выполнения и вызывается снова из обработчика прерывания , глобальная переменная может находиться в состоянии, в котором были обновлены только 32 бита. Язык программирования может предоставлять гарантии атомарности для прерываний, вызванных внутренним действием, например переходом или вызовом. Тогда функция f в выражении вроде (global:=1) + (f()), где порядок вычисления подвыражений может быть произвольным на языке программирования, глобальная переменная будет либо установлена ​​в 1, либо в ее предыдущее значение, но не в промежуточном состоянии, где была обновлена ​​только часть. (Последнее может произойти в C , поскольку выражение не имеет точки последовательности .) Операционная система может предоставлять гарантии атомарности для сигналов , таких как системный вызов, прерванный сигналом, не имеющим частичного эффекта. Аппаратное обеспечение процессора может обеспечивать гарантии атомарности прерываний , например прерываемые инструкции процессора, не имеющие частичного эффекта.

Примеры [ править ]

Чтобы проиллюстрировать реентерабельность, в этой статье в качестве примера используется C : служебная функция swap(), который принимает два указателя и транспонирует их значения, а также процедуру обработки прерываний, которая также вызывает функцию подкачки.

Ни реентерабельный, ни потокобезопасный [ править ]

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

ИНТ   ТМП  ; 

  void   swap  (  int  *   x  ,   int  *   y  ) 
 { 
     tmp   =   *  x  ; 
      *  х   =   *  у  ; 
      /* Здесь аппаратное прерывание может вызвать isr().   */ 
     *  y   =   tmp  ;     
  } 

 void   isr  () 
 { 
     int   x   знак равно   1  ,   y   знак равно   2  ; 
      поменять местами  (  &  x  ,   &  y  ); 
  } 

Потокобезопасный, но не реентерабельный [ править ]

Функция swap() в предыдущем примере можно сделать потокобезопасным, сделав tmp локальный поток . Он по-прежнему не может быть реентерабельным, и это будет продолжать вызывать проблемы, если isr() вызывается в том же контексте, что и уже выполняющийся поток swap():

_Thread_local   int   tmp  ; 

  void   swap  (  int  *   x  ,   int  *   y  ) 
 { 
     tmp   =   *  x  ; 
      *  х   =   *  у  ; 
      /* Здесь аппаратное прерывание может вызвать isr().   */ 
     *  y   =   tmp  ;     
  } 

 void   isr  () 
 { 
     int   x   знак равно   1  ,   y   знак равно   2  ; 
      поменять местами  (  &  x  ,   &  y  ); 
  } 

Реентерабельный и потокобезопасный [ править ]

Реализация swap() который выделяет tmp в стеке , а не глобально, и он вызывается только с неразделяемыми переменными в качестве параметров. [б] является одновременно потокобезопасным и реентерабельным. Потокобезопасен, поскольку стек является локальным по отношению к потоку, и функция, действующая только на локальные данные, всегда будет давать ожидаемый результат. Нет доступа к общим данным, поэтому нет гонки за данными.

void   swap  (  int  *   x  ,   int  *   y  ) 
 { 
     int   tmp  ; 
      ТМП   =   *  х  ; 
      *  х   =   *  у  ; 
      *  у   =   ТМП  ;       /* Здесь аппаратное прерывание может вызвать isr().   */ 
 } 

 void   isr  () 
 { 
     int   x   =   1  ,   y   =   2  ; 
      поменять местами  (  &  x  ,   &  y  ); 
  } 

Обработчик реентерабельного прерывания [ править ]

Обработчик повторного прерывания — это обработчик прерываний , который повторно разрешает прерывания на ранних этапах обработчика прерываний. Это может уменьшить задержку прерывания . [6] В общем, при программировании процедур обработки прерываний рекомендуется как можно скорее повторно разрешить прерывания в обработчике прерываний. Эта практика помогает избежать потери прерываний. [7]

Дальнейшие примеры [ править ]

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

интервал   v   =   1  ; 

  int   f  () 
 { 
     v   +=   2  ; 
      вернуть   v  ; 
  } 

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

В приведенном выше f() зависит от непостоянной глобальной переменной v; таким образом, если f() прерывается во время выполнения ISR, который изменяет v, затем снова войдите в f() вернет неправильное значение v. Значение v и, следовательно, возвращаемое значение f, невозможно предсказать с уверенностью: они будут различаться в зависимости от того, изменилось ли прерывание. v в течение fказнь. Следовательно, fне является реентерабельным. Ни то, ни другое g, потому что он вызывает f, который не является реентерабельным.

Эти слегка измененные версии являются реентерабельными:

int   f  (  int   я  ) 
 { 
     возвращение   я   +   2  ; 
  } 

 Int   г  (  int   я  ) 
 { 
     возвращение   ж  (  я  )   +   2  ; 
  } 

Ниже функция является потокобезопасной, но не (обязательно) реентерабельной:

int   function  () 
 { 
     mutex_lock  (); 

      // ... 
     // тело функции 
     // ... 

     mutex_unlock  (); 
  } 

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

Примечания [ править ]

  1. ^ Программа, которая сериализует самомодификацию, может быть реентерабельной, а чистая процедура, обновляющая глобальные данные без надлежащей сериализации, может не быть реентерабельной.
  2. ^ Если isr() вызывает swap() с одной или двумя глобальными переменными в качестве параметров, то swap() не будет реентерабельным.

См. также [ править ]

Ссылки [ править ]

  1. ^ Керриск 2010 , с. 657 .
  2. ^ Ралстон 2000 , с. 1514–1515.
  3. ^ «pthread_cond_init() — инициализировать переменную условия» . Центр знаний IBM . Проверено 5 октября 2019 г.
  4. ^ Прешинг, Джефф (18 июня 2013 г.). «Атомарные и неатомарные операции» . Прешинг по программированию . Архивировано из оригинала 3 декабря 2014 г. Проверено 24 апреля 2018 г.
  5. ^ Керриск 2010 , с. 428 .
  6. ^ Слосс и др. 2004 , с. 342 .
  7. ^ Регер, Джон (2006). «Безопасное и структурированное использование прерываний в реальном времени и встроенном программном обеспечении» (PDF) . Справочник по системам реального времени и встроенным системам . ЦРК Пресс . Архивировано (PDF) из оригинала 24 августа 2007 г. - на веб-сайте автора в Школе вычислительной техники Университета Юты.

Цитируемые работы [ править ]

Дальнейшее чтение [ править ]

Arc.Ask3.Ru: конец оригинального документа.
Arc.Ask3.Ru
Номер скриншота №: 332E1F1F72F551D752B08F4912162366__1706992800
URL1:https://en.wikipedia.org/wiki/Reentrant_(subroutine)
Заголовок, (Title) документа по адресу, URL1:
Reentrancy (computing) - Wikipedia
Данный printscreen веб страницы (снимок веб страницы, скриншот веб страницы), визуально-программная копия документа расположенного по адресу URL1 и сохраненная в файл, имеет: квалифицированную, усовершенствованную (подтверждены: метки времени, валидность сертификата), открепленную ЭЦП (приложена к данному файлу), что может быть использовано для подтверждения содержания и факта существования документа в этот момент времени. Права на данный скриншот принадлежат администрации Ask3.ru, использование в качестве доказательства только с письменного разрешения правообладателя скриншота. Администрация Ask3.ru не несет ответственности за информацию размещенную на данном скриншоте. Права на прочие зарегистрированные элементы любого права, изображенные на снимках принадлежат их владельцам. Качество перевода предоставляется как есть, любые претензии не могут быть предъявлены. Если вы не согласны с любым пунктом перечисленным выше, немедленно покиньте данный сайт. В случае нарушения любого пункта перечисленного выше, штраф 55! (Пятьдесят пять факториал, денежную единицу можете выбрать самостоятельно, выплаичвается товарами в течение 7 дней с момента нарушения.)