OOP Course
Сьогодні

Підрозділ 15.6

Клас Mutex

15.6. Клас Mutex Mutex від англ. mutual exclusion — взаємне виключення — примітив синхронізації, що схожий на lock , але має ключову відмінність: Mutex може працювати між процесами , а не лише між потоками одно

15.6. Клас Mutex

Mutex (від англ. mutual exclusion — взаємне виключення) — примітив синхронізації, що схожий на lock, але має ключову відмінність: Mutex може працювати між процесами, а не лише між потоками одного процесу. Це робить його незамінним інструментом у ситуаціях, коли потрібно координувати доступ до ресурсу між кількома запущеними програмами.

Крім міжпроцесного режиму, Mutex підтримує і внутрішньопроцесну синхронізацію. Однак він суттєво повільніший за lock: внутрішньопроцесний lock — це операція на рівні CLR без звернень до ядра ОС; Mutex — це об'єкт операційної системи, і кожне захоплення/звільнення вимагає системного виклику. Тому для синхронізації потоків усередині одного процесу зазвичай краще обирати lock. Mutex обирають тоді, коли міжпроцесна синхронізація є вимогою.

API класу Mutex

Метод / конструктор Опис
new Mutex() Локальний (внутрішньопроцесний) mutex, починає у вільному стані
new Mutex(bool initiallyOwned) true — поточний потік одразу стає власником
new Mutex(bool initiallyOwned, string name) Іменований (міжпроцесний) mutex. name — глобальна системна назва
WaitOne() Захоплює mutex. Блокує, якщо зайнятий
WaitOne(int ms) Захоплення з таймаутом. Повертає bool
ReleaseMutex() Звільняє mutex. Лише потік-власник може це зробити
Dispose() Звільняє системний ресурс

Важлива особливість: mutex є реентерабельним (recursive). Якщо потік, що вже тримає mutex, знову викликає WaitOne(), він пройде без блокування. Але він зобов'язаний викликати ReleaseMutex() рівно стільки разів, скільки викликав WaitOne() — інакше mutex залишиться захопленим.

Базовий приклад: захист спільного ресурсу

Спочатку розглянемо Mutex у ролі звичайного внутрішньопроцесного замку — для розуміння API:

Зверніть на паттерн try/finally: ReleaseMutex() розміщується у блоці finally, щоб гарантувати звільнення навіть при виникненні винятку. Якщо mutex не буде звільнений, всі інші потоки заблокуються назавжди.

Іменований Mutex — захист між процесами

Головна сила Mutex — іменований варіант, що є спільним об'єктом ОС. Два процеси, що створюють Mutex з однаковим іменем, отримують посилання на той самий системний об'єкт:

Параметр out createdNew повертає true, якщо цей процес створив mutex (тобто є першим), або false, якщо mutex вже існував (інший процес вже запущений). Префікс Global\\ означає, що mutex видимий для всіх сесій ОС; Local\\ (або без префікса) — лише для поточної сесії.

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

Тайм-аут очікування

Mutex.WaitOne(ms) дозволяє не блокуватись вічно:

AbandonedMutexException

Коли потік завершується, не звільнивши mutex, інші потоки, що чекають, отримають виняток AbandonedMutexException. Це захисний механізм: наступний потік-власник отримає сигнал, що попередній «впав» без коректного завершення, і може прийняти рішення щодо стану спільного ресурсу.

Mutex vs lock: підсумок

Характеристика lock Mutex
Область дії Потоки одного процесу Потоки та різні процеси
Продуктивність Дуже висока (без ОС-викликів) Нижча (об'єкт ядра ОС)
Реентерабельність Ні (нова спроба — дедлок) Так (рекурсивне захоплення)
Таймаут очікування Ні WaitOne(ms)
AbandonedMutexException Ні Так
Типовий сценарій Захист даних усередині програми Singleton-процес, спільний файл

Правило вибору: для синхронізації потоків усередині одного додатку — lock; якщо потрібна координація між кількома запущеними програмами або захист системного ресурсу — Mutex.

Розроблено Tomka Yurii · © 2026 ·