
- •Процеси та потоки Процеси
- •Модель процесу
- •Створення процесу
- •Завершення процесу
- •Ієрархія процесів
- •Стани процесу
- •Реалізація процесу
- •Класична модель потоків
- •Реалізація потоків в просторі користувача
- •Реалізація потоків в просторі ядра
- •Активація планувальника
- •Спливаючі потоки
- •Взаємодія процесів
- •Змагання між процесами
- •Критична секція
- •Блокуючі змінні
- •Строге чергування
- •Алгоритм Петерсона
- •Команда tsl
- •Завдання виробника і споживача. Sleep і wakeup.
- •Семафори
- •М’ютекси
- •Монітори
- •Завдання алгоритму планування
Строге чергування
Принцип строгого чергування показано на рис.
Спочатку процес 0 перевіряє значення turn, визначає, що воно дорівнює нулю, і входить в критичну область. Процес 1 також визначає, що значення цієї змінної дорівнює нулю, через що знаходиться в короткому циклі, постійно перевіряючи, коли turn отримає значення 1. Постійна перевірка значення змінної, поки вона не набуде якесь значення, називається активним очікуванням. Коли процес 0 виходить з критичної області, він встановлює значення змінної turn в 1, дозволяючи процесу 1 увійти в його критичну область.
Строга послідовність виконання стає вузьким місцем, коли один процес працює значно повільніше іншого. Так процес 0 може вступити у свою критичну область лише, якщо значення змінної turn дорівнює 0, а встановлення turn в 0 здійснює лише процес 1, тобто процес 0 не зможе вступити в критичну секцію повторно, а лише після процесу 1.
Ця ситуація порушує сформульовану раніше третю умову: процес 0 виявляється заблокованим тим процесом, який не перебуває у своїй критичної області.
Алгоритм Петерсона
Перед входом в свою критичну область кожен процес викликає функцію enter_region, передаючи їй в якості аргументу свій власний номер процесу, 0 або 1. Після завершення роботи із загальними змінними процес, викликає функцію leave_region.
Спочатку процес 0 викликає функцію enter_region. Він демонструє свою зацікавленість, встановлюючи свій елемент масиву і привласнюючи змінної turn значення 0. Оскільки процес 1 зацікавленості у вході в критичну область не виявив, функція enter_region негайно ж повертає управління. Тепер, якщо процес 1 викличе функцію enter_region, він зависне до тих пір, поки interested [0] не отримає значення FALSE, а це відбудеться тільки в тому випадку, якщо процес 0 викличе функцію leave_region, щоб вийти з критичної області.
Тепер розглянемо випадок, коли обидва процеси практично одночасно викликають функцію enter_region. Обидва вони будуть зберігати свій номер процесу у змінній turn. У розрахунок буде братися останнє збереження, оскільки перше буде переписано і втрачено. Припустимо, що процес 1 зберіг свій номер останнім і turn має значення 1. Коли обидва процеси доберуться до оператора while, процес 0 не виконає його жодного разу і увійде в свою критичну область. Процес 1 увійде в цикл і не буде входити в свою критичну область доти, поки процес 0 не вийде з своєї критичної області.
Команда tsl
В багатьох архітектурах є команда TSL яка зчитує вміст слова пам'яті lock в регістр, а за адресою пам'яті, відведеному для lock, записує ненульове значення. При цьому гарантується неподільність операцій читання слова і збереження у ньому нового значення - ніякої інший процес не може отримати доступ до слова в пам'яті, поки команда не завершить свою роботу. Центральний процесор, що виконує команду TSL, блокує шину пам'яті, забороняючи іншим центральним процесорам доступ до пам'яті до тих пір, поки не буде виконана ця команда.
На рисунку показано реалізацію входу у критичну область за допомогою команди TSL
Перша команда копіює колишнє значення змінної lock в регістр, а потім привласнює їй значення 1. Потім колишнє значення порівнюється з нулем. Якщо воно ненульове, значить, блокування вже було встановлено, тому програма просто повертається на початок і проводить повторну перевірку значення змінної. Рано чи пізно це значення перетвориться в 0 (коли процес, який перебував у своїй критичній області, завершить в ній роботу і відбудеться вихід з підпрограми з установкою блокування). Зняття блокування здійснюється досить просто. Для цього програмою досить привласнити змінної lock нульове значення. Для цього не потрібні ніякі спеціальні команди синхронізації.
Альтернативою команді TSL служить команда XCHG, яка використовується для низькорівневої синхронізації усіма центральними процесорами сімейства Intel x86.
Недолік – необхідність перебування в режимі активного очікування. Цей підхід не лише призводить до марної трати процесорного часу, але може також призвести до виникнення зовсім несподіваних ефектів. Розглянемо комп'ютер з двома процесами: H, з високим ступенем пріоритету, і L, з низьким ступенем пріоритету. Правила планування їх роботи передбачають, що H виконується відразу ж після входу в стан готовності. У певний момент, коли L знаходиться в критичній області, H входить в стан готовності (наприклад, після завершення операції введення-виведення). Тепер H входить в режим активного очікування, але оскільки поки виконується процес H, виконання L НЕ планується, у L не залишається шансів вийти зі своєї критичної області, тому H перебуває в нескінченному циклі. На подібну ситуацію іноді посилаються як на проблему інверсії пріоритету.