Захват ділянок файлів
Семафори зручні при синхронізації доступу до єдиного ресурсу,
такому як принтер або неділима структура даних. Якщо ж нам потрібна
синхронізація доступу до ресурсу, що має внутрішню структуру,
наприклад до файлу з базою даних, краще використовувати інші методи.
Якщо говорити саме про файл, виявляється зручним блокувати доступ до
ділянок файлу. При цьому доцільно ввести двох типів захватів: для читання
і для запису. Захват для читання дозволяє іншим
ниткам читати із заблокованої ділянки і навіть ставити туди таке ж
блокування, але забороняє писати в цю ділянку і, тим більше, блокувати його
для запису. Цим досягається упевненість в тому, що структури даних, що
прочитуються із захопленої ділянки, ніким не модифікуються, тому
гарантована їх цілісність і несуперечність.
У свою чергу захват для запису забороняє
всім, окрім нитки, що встановила його, будь-який доступ до заблокованої
ділянки файлу. Це означає, що дана ділянка файлу зараз модифікуватиметься,
і цілісність даних в нім не гарантована.
Блокування ділянок файлу в Unix
Захват ділянок файлу як засіб синхронізації був відомий ще
з 60-х років, але в тому вигляді, який описаний в стандартах ANSI і POSIX,
він був реалізований в ОС UNIX на початку 70-х.
У UNIX можливі два режими захвату: допустима (advisory) і обов'язкова
(mandatory). Як та, так і інше блокування може бути блокуванням читання
або запису. Допустиме блокування є "блокуванням для чесних":
вона не робить впливу на підсистему введення-виводу, тому програма,
не перевіряюча блокувань або що ігнорує їх, зможе писати або
читати із заблокованої ділянки без проблем. Обов'язкове блокування
вимагає великих накладних витрат, але забороняє фізичний доступ до файлу:
читання або запис, залежно від типа блокування.
При роботі
із структурами даних, що розділяються, в ОЗУ було б зручно мати аналогічні
засоби, але їх реалізація веде до великих накладних витрат, навіть
на системах з віртуальною пам'яттю, тому жодна з відомих авторові систем таких
засобів не має. Бібліотека POSIX threads надає своєрідну форму
мутекса, read/write lock, який, як і описані файлові примітиви,
може бути багато разів захоплений для читання і лише однократно
— для запису. Проте ми повинні заводити такий примітив для кожної
одиниці ресурсу, що розділяється, і не можемо одним викликом захопити
відразу багато подібних одиниць.
Втім, в сучасних версіях системи UNIX є можливість відображувати
файл у віртуальну пам'ять. Використовуючи при цьому допустиме блокування ділянок
файлу, програми можуть синхронизироовать доступ до нього (обов'язкове блокування
робить неможливим відображення в пам'ять).
|