В чем разница между реентрантной функцией и рекурсивной функцией в C? - PullRequest
21 голосов
/ 04 ноября 2008

В Си я знаю о рекурсивной функции, но я слышал о функции повторного входа.

Что это? И какая между ними разница?

Ответы [ 8 ]

22 голосов
/ 04 ноября 2008

Легче запомнить, когда вы понимаете, что означает этот термин.

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

Другими словами, когда две задачи могут выполнять функцию одновременно, не мешая друг другу, функция возвращается. Функция не возвращается, когда выполнение одной задачи влияет на влияние другой задачи. Обычно это тот случай, когда используется глобальное состояние или данные. Функция, которая использует только локальные переменные и аргументы, обычно реентерабельна.

16 голосов
/ 04 ноября 2008

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

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

strtok() - это классический случай функции в стандартной библиотеке языка C, которая хорошо известна , а не для повторного входа.

[Редактировать]: В комментариях есть куча идей, разъяснений и исправлений, поэтому, пожалуйста, прочитайте их! Спасибо за помощь, ребята.

10 голосов
/ 04 ноября 2008

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

10 голосов
/ 04 ноября 2008

То, что раскручивается первоначально , в основном верно, за исключением того, что оно не ограничено многопоточностью (кроме того, защита глобальных данных с помощью блокировок делает их безопасными для потоков - но не обязательно -entrant). [Редактировать] Он исправил свой пост, чтобы объяснить это сейчас: -)

Функция также может быть повторно введена в том же потоке в результате рекурсии - прямо или косвенно (т. Е. Функция a вызывает функцию b, которая вызывает функцию c, которая вызывает функцию a).

Конечно, если вы защитили от повторного входа на основании того, что несколько потоков могут вызывать его, то вы также охвачены рекурсивными случаями. Однако это не так.

3 голосов
/ 24 ноября 2008

Вот оно:

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

  • Потоковая функция может вызываться одновременно несколькими потоками, когда каждый вызов ссылается на общие данные. Весь доступ к общим данным сериализуется.

Бесстыдно украдено из руководства Qt. Но это краткое и краткое определение. По сути, не реентерабельная функция также не является recursion-safe.

Теперь, что такое recursive функция? Это своего рода определение функции. Рекурсивные функции определяются в терминах самих себя. Они уменьшают ввод, вызывают себя, пока не выясняется основной случай без необходимости повторного вызова.

Итак, у нас есть две вещи.

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

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

1 голос
/ 05 июня 2012

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

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

И, конечно, напомним, что реентерабельная функция - это не то же самое, что рекурсивная функция ... совершенно другое понятие ... Функция Rerantrant - это функция, которая гарантирует то, что может хорошо работать в многопоточной среде. значит, в то время как функция является доступом одним потоком, другой поток может вызвать его ... значит, есть отдельный стек выполнения и обработка для каждого ... Поэтому функция не должна содержать статических или разделяемых переменных, которые могут повредить или помешать выполнению ..

означает, что оно не должно содержать статических или общих переменных ....

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

И, конечно, напомним, что реентерабельная функция - это не то же самое, что рекурсивная функция ... совершенно другое понятие ...

Подробнее: http://wiki.answers.com/Q/What_is_a_reentrant_function#ixzz1wut38jLF Вики: http://en.wikipedia.org/wiki/Reentrancy_%28computing%29

0 голосов
/ 27 января 2012

Весь рекурсивный код рекурентный ... но не весь рекурсивный код рекурсивный.

0 голосов
/ 03 декабря 2010

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

...