Page 84 - 4636
P. 84
3.4 Блокування файлів
Уявіть ситуацію, коли два клієнта одночасно намагаються замовити товар. Ця ситуація виникає не
настільки вже рідко, особливо коли веб-сайт починає обробляти трафік істотного обсягу. Що
станеться, якщо один клієнт викличе функцію fopen() і почне запис, а потім другий клієнт також
викличе функцію fopen() і теж зробить спробу запису? Яким у результаті всього цього виявиться
вміст файлу? Чи буде спочатку записане перше замовлення, а потім друге, чи навпаки? Чи буде взагалі
записане перше замовлення або друге? Або ж вміст буде сумішшю двох замовлень? Відповіді на ці
питання залежать від конкретної використовуваної операційної системи, але найчастіше точно
відповісти на них неможливо.
Щоб уникнути подібних проблем, використовується механізм блокування файлів. У РНР
блокування реалізується за допомогою функції flock(). Ця функція повинна викликатися після
відкриття файлу, але перед зчитуванням даних з цього файлу або їх записом у цей файл.
Прототип функції flock() виглядає таким чином:
bool flock (resource fp, int operation [, int &wouldblock]) ;
У функцію необхідно передати покажчик на відкритий файл і константу, що представляє вид
необхідного блокування. Функція повертає значення true, якщо блокування були успішно виконані, і
false - у протилежному випадку. Необов'язковий третій параметр повинен містити true, якщо
запитуване блокування може привести до блокування поточного процесу (тобто до його очікування).
Можливі значення параметра operation (операція) перелічені в табл. 3.2. Ці можливі значення
зазнали деяких змін у версії РНР 4.0.1 тому в таблиці представлені обидва набори значень.
Таблиця 3.2. Значення параметра operation функції flock()
Значення параметра Опис
operation
L0CK_SH Блокування читання. Файл може використовуватися
у ранніх версіях - 1) спільно з іншими додатками, що зчитують.
L0CK_EX Блокування запису. Це монопольний режим . Файл
(у ранніх версіях - 2) не доступний для спільного використання.
L0CK_UN Скасування існуючого блокування
(у ранніх версіях - 3)
L0CK_NB Забороняються інші спроби блокування під час
(у ранніх версіях - 4) виконання поточного блокування
Якщо функція flock() буде використана, її слід включити в усі сценарії, в яких задіюється даний
файл. В іншому випадку її застосування не має сенсу.
Функція flock() не працює з системою NFS (Network File System - мережева файлова система) і
іншими мережевими файловими системами. Вона також не працює із застарілими файловими
системами, які не підтримують таке блокування, наприклад, FAT (File Allocation Table - таблиця
розміщення файлів). У середовищі деяких операційних систем вона реалізована на рівні процесів і не
буде працювати коректно, якщо використовується API (Application Programming Interface - інтерфейс
програмування додатків) багатопоточного сервера.
Але що буде, якщо два сценарії спробують одночасно запросити блокування? Це призвело б до
стану змагань, коли процеси змагаються за встановлення блокування, в умовах якого невідомо, якому
з них це вдасться, що, у свою чергу, могло б породити нові проблеми. Значно більшого ефекту можна
досягти при використанні однієї із систем управління базами даних.
81