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
   79   80   81   82   83   84   85   86   87   88   89