Реєнтерабельним системних функцій

У багатозадачному системі не можна виключити можливість того, що перемикання процесів станеться під час виконання витісняється процесом небудь із системних функцій. При цьому виконання функції не буде завершено, воно буде перервано на середині. Передбачається, що виконання функції буде завершено пізніше, коли перерваний процес знову буде обраний на виконання.

Проблема полягає в тому, що новий поточний процес може викликати ту ж саму системну функцію. Виникає питання: чи можливо коректне виконання другого виклику функції, якщо до цього моменту не закінчено виконання першого виклику тієї ж функції?

Простий приклад подібної ситуації - запуск в ОС декількох програм, кожна з яких блокується на очікуванні клавіатурного введення, викликавши для цього одну і ту ж системну функцію вводу.

Функція або процедура, для якої можливе коректне виконання її повторного виклику до завершення першого виклику, називається реєнтерабельним або повторно-входимость.

Проблема реєнтерабельним функцій виникає в програмуванні та по абсолютно іншому приводу, не пов'язаному з реалізацією ОС. Мова йде про рекурсивних функціях, тобто функціях, які можуть прямо або побічно викликати самі себе. Давно відома і основна причина нереентерабельності функцій. Вона полягає у використанні одних і тих же елементів пам'яті для формальних параметрів і локальних змінних при різних викликах функції. Дійсно, якщо при першому виклику функції в осередок локальної змінної X буде занесено, наприклад, число 10, а при другому - число 20, то після відновлення виконання першого виклику значення X буде невірним.

Ліки від цієї форми нереентерабельності також давно відомо і вбудовано в усі поважають себе мови програмування, починаючи з C і Pascal. Воно полягає в тому, що пам'ять для формальних параметрів і локальних змінних повинна виділятися в стеку програми, при цьому кожен новий вкладений виклик отримує свій набір осередків для змінних.

Для випадку багатозадачної системи використання єдиного стека неприйнятно, оскільки виклики функцій не є вкладеними, тобто перший виклик може завершитися раніше, ніж другий, що призвело б до невірного використання стека. Кожен процес отримує свій власний стек, що є частиною контексту процесу.

Ще одна причина нереентерабельності стосується тих функцій введення / виводу, які запускають операцію і потім чекають її завершення. Повторне звернення до того ж пристрою до завершення

першого виклику може привести до помилки. У даному випадку система повинна відстежувати стан пристрою і блокувати другий виклик до звільнення пристрою.

Проблема реєнтерабельним системних функцій значно гостріше стоїть для ОС з витісняючої диспетчеризацією, оскільки перемикання процесу може трапитися при виконанні будь-якої функції. При невитесняющей диспетчеризації досить забезпечити реєнтерабельним реалізацію лише невеликого числа блокуючих функцій.

При переході від невитесняющей Windows 3.x до витісняючої Windows 95 одна із серйозних проблем полягала в збереженні коду великої кількості нереентерабельних системних функцій. Проблему «вирішили» шляхом введення семафора, блокуючого повторний виклик для великого числа функцій. Неприємним наслідком цього стало взаємне гальмівний вплив процесів. У Windows NT цієї проблеми немає, всі функції реалізовані реєнтерабельним.