Засоби синхронізації і взаємодії процесів - студопедія
Проблемна ситуація: Уявімо собі двох студентів, яким потрібно попрацювати з однієї і тієї ж книгою, наявної в бібліотеці в єдиному екземплярі. Вони одночасно прийшли в бібліотеку, але один з них спочатку пішов в Новомосковскльний зал і, зайнявши єдине вільне місце, відправився в книжкове сховище, а інший - навпаки, почав з того, що отримав книгу, а потім пішов у Новомосковскльний зал шукати місце. В результаті жоден з них не може виконати роботу, так як для цього їм не вистачає необхідного ресурсу. Чи можна вважати, що в даному випадку відбулася взаємне блокування, або, іншими словами, клінч? Відповідь: Ні, в даному випадку ми маємо справу не з клінчем, а з чергою. Дійсно, студент, який чекає в Новомосковскльном залі, може бути «розблоковано» в результаті звільнення будь-якого іншого місця в Новомосковскльном залі, а потім він, виконавши свою роботу і здавши книгу, «розблокує» іншого студента, який чекає в книжковому сховищі. Для того щоб ситуація могла бути названа клінчем, слід доповнити задачу ще однією умовою-в Новомосковскльном залі є тільки одне робоче місце.
Процеси називаються паралельними, якщо вони існують одночасно. Паралельні процеси можна розділити на наступні дві групи:
· Незалежні (що не потребують у взаємодії один з одним) процеси;
· Асинхронні (взаємодіючі і потребують періодичної син-хронізації) процеси.
Синхронізація процесів - використання спеціальних атоміческіе опера-цій для здійснення взаємодії між процесами.
Процесам часто потрібно взаємодіяти один з одним, наприклад, один процес може передавати дані іншому процесу, або кілька процесів можуть обробляти дані із загального файлу. У всіх цих випадках виникає проблема синхронізації процесів, яка може вирішуватися припиненням та активізацією процесів, організацією черг, блокуванням і звільненням ресурсів.
Нехтування питаннями синхронізації процесів, що виконуються в режимі мультипрограмування, може привести до їх неправильної роботи або навіть до краху системи. Розглянемо, наприклад (рисунок 1), програму друку файлів (принт-сервер). Ця програма друкує по черзі всі файли, імена яких послідовно в порядку надходження записують в спеціальний загальнодоступний файл "замовлень" інші програми. Особлива змінна NEXT, також доступна всім процесам-клієнтам, містить номер першої вільної для запису імені файлу позиції файлу "замовлень". Процеси-клієнти Новомосковскют цю змінну, записують у відповідну позицію файлу "замовлень" ім'я свого файлу і нарощують значення NEXT на одиницю. Припустимо, що в деякий момент процес R вирішив роздрукувати свій файл, для цього він прочитав значення змінної NEXT, значення якої для визначеності припустимо рівним 4. Процес запам'ятав це значення, але помістити ім'я файлу не встиг, так як його виконання було перервано (наприклад, в наслідок вичерпання кванта). Черговий процес S, який бажає роздрукувати файл, прочитав те ж саме значення змінної NEXT, помістив в четверту позицію ім'я свого файлу і наростив значення змінної на одиницю. Коли в черговий раз управління буде передано процесу R, то він, продовжуючи своє виконання, в повній відповідності зі значенням поточної вільної позиції, отриманим під час попередньої ітерації, запише ім'я файлу також в позицію 4, поверх імені файлу процесу S.
Таким чином, процес S ніколи не побачить свій файл роздрукованим. Складність проблеми синхронізації полягає в нерегулярності виникаючих ситуацій: в попередньому прикладі можна уявити і інший розвиток подій: були втрачені файли декількох процесів або, навпаки, не був загублений жоден файл. В даному випадку все визначається взаємними швидкостями процесів і моментами їх переривання. Тому налагодження взаємодіючих процесів є складним завданням.
Ситуації подібні тій, коли два або більше процесів обробляють колективні дані, і кінцевий результат залежить від співвідношення швидкостей процесів, називаються гонками.
Критичний ресурс - ресурс, який допускає обслуговування тільки одного процесу за один раз. Якщо кілька процесів хочуть використовувати крити-ний ресурс в режимі поділу, то їм слід синхронізувати свої дії, щоб ресурс завжди знаходився в розпорядженні не більше ніж од-ного з них.
Критичні ділянки - ділянки процесу, де відбувається звернення до кри-тичного ресурсу. Критичні ділянки повинні бути взаємовиключними, т. Е. В кожен момент часу не більше ніж один процес може бути зайнятий виконанням свого критичного щодо деякого ресурсу участ-ка. Забезпечення (підтримка механізму) взаємовиключення - ключова за-дача паралельного програмування.
Блокування - запобігання виконання будь-ким чого-небудь. Процес повинен встановлювати блокування перед входом в критичний ділянку і знімати її після виходу. Природно, якщо дільниця заблокована, то дру-гой процес повинен чекати зняття блокування.
Рис.1. Приклад необхідності синхронізації
Типовим прикладом критичного ресурсу є колективна змін-ва, що підсумовує деяку величину (назвемо її лічильник). Критичні ділянки процесів тоді можуть містити наступний код:
лічильник: = лічильник + 1.
Гонки - ситуація, коли два або більше процесів обробляють розділяти-мі дані і кінцевий результат залежить від співвідношення швидкостей їх виконання.
Важливим поняттям синхронізації процесів є поняття "критична секція" програми (CS).
Критична секція - це частина програми, в якій здійснюється доступ до даних, що розділяються.
Щоб уникнути наслідків гонок по відношенню до деякого ресурсу, необхідно забезпечити, щоб у кожен момент в критичній секції, пов'язаної з цим ресурсом, перебував максимум один процес. Цей прийом називають взаємним винятком. Найпростіший спосіб забезпечити взаємне виключення - дозволити процесу, що знаходиться в критичній секції, забороняти все переривання. Однак цей спосіб не годиться, так як небезпечно довіряти управління системою користувача процесу; він може надовго зайняти процесор, а у випадку краху процесу в критичній області крах зазнає вся система, тому що переривання ніколи не будуть вирішені.
Іншим способом є використання блокуючих змінних. З кожним ресурсом зв'язується двоичная змінна, яка приймає значення 1, якщо ресурс вільний (тобто жоден процес не знаходиться в даний момент в критичній секції, пов'язаної з даним процесом), і значення 0, якщо ресурс зайнятий. На рис.2 показаний фрагмент алгоритму процесу, що використовує для реалізації взаємного виключення доступу до ресурсу D блокує змінну F (D). Перед входом в критичну секцію процес перевіряє, чи вільний ресурс D. Якщо він зайнятий, то перевірка циклічно повторюється, якщо вільний, то значення змінної F (D) встановлюється в 0, і процес входить в критичну секцію. Після того, як процес виконає всі дії з ресурсом D, значення змінної F (D) знову встановлюється рівним 1.
Якщо всі процеси написані з використанням вищеописаних угод, то взаємне виключення гарантується. Слід зауважити, що операція перевірки і установки блокує змінної повинна бути неподільною. Пояснимо це. Нехай в результаті перевірки змінної процес визначив, що ресурс вільний, але відразу після цього, не встигнувши встановити змінну в 0, був перерваний. За час його припинення інший процес зайняв ресурс, увійшов в свою критичну секцію, але також був перерваний, не завершивши роботи з ресурсом.

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