Большой архив статей, книг, документации по программированию, вебдизайну, компьютерной графике, сетям, операционным системам и многому другому
 
<Добавить в Избранное>    <Сделать стартовой>    <Реклама на сайте>    <Контакты>
  Главная Документация Программы Обои   Экспорт RSS E-Books
 
 

   Интернет технологии -> PHP -> Параллельное выполнение скриптов


Параллельное выполнение скриптов PHP может нарушить целостность информации в файлах

Здесь рассматривается вопрос, что бывает, если запустить некий скрипт почти одновременно (что происходит, например, при большой нагруженности сервера) несколько раз, т.е. запустить несколько копий одного и того же скрипта. И к чему это может привести.

Ошибка программы простого текстового счетчика

Давайте сделаем такую программу. Итак, у нас есть какая-то страница, на которой хочется повесить счетчик. Обудим алгоритм:

  • считать число из файла
  • записать увеличенное число обратно
  • вывести его на экран


Согласитесь, программа простая, но может привести к ошибке, что и показано ниже.

<? // верхняя часть страницы // код счетчика: $counter=file("counter.txt"); // прочитали файл в массив $counter $f=fopen("counter.txt","w+"); // открыли файл на запись fputs($f,$counter[0]+1); // записали "число + 1" fclose($f); // закрыли файл echo $counter[0]+1; // вывели число на экран // нижняя часть страницы ?>



Если вызывать данную программу очень часто, значение счетчика иногда будет обнуляться. Это произойдет из-за того, что в некоторый момент программа прочитает из файла пустое значение, к которому потом прибавляется единица ("пусто" + число 1 = число 1). Собственно, это и есть сброс счетчика.

Рассмотрим подробно, когда это произойдет. Представьте, что в один момент времени стартовали 2 копии данного скрипта. Одновременно ничего нигде не проиходит, в т.ч. и запуск скриптов, но время между запуском может быть очень маленькое. Процессор выполняет скрипты с разной скоростью, т.е. вы не должны удивляться тому, в каком порядке далее будут рассматриваться команды. Итак, ход программы (на примере "скрипта N1" и "скрипта N2"):

скрипт

команда

комментарий (что сделает данная команда)

1 запуск первого скрипта --
1 $counter=file("counter.txt"); в переменной (массиве $counter) теперь храниться текущее число счетчика. Допустим, там было 1234, тогда это число будет в переменной $counter[0].
2 запуск второго скрипта --
1 $f=fopen("counter.txt","w+");
  • открывает файл
  • обнуляет его
  • если файл не был создан, создает его (если позволят права). Но файл создан нами заранее, этот вариант исключен.
  • 2 $counter=file("counter.txt"); читает содержимое пустого файла и записывает в массив $counter пустой массив. Переменная $counter[0] не существует.
    1 fputs($f,$counter[0]+1); пишет в файл число 1234 (т.к. в $counter[0] лежит число 1234)
    2 $f=fopen("counter.txt","w+"); см. комментарий выше
    1 fclose($f); и конец работы
    2 fputs($f,$counter[0]+1); записывает в файл число 1, т.к результат сложения несуществующей переменной и числа 1 равен числу 1
    2 fclose($f); и конец работы


    Как видите, если 2 параллельно работающих скрипта, выполнять именно в такой последовательности, то файл будет обнулен. Если вы попробуете этого добиться, вылняя частую перезагрузку страницы в браузере, то у вас скорее всего ничего не выйдет. Чтобы убедиться, что файл будет таки обнулен, воспользуйтесь утилитой ab (которая умеет генерировать, в течении длительного времени большое число, параллельных запросов к скиптам), либо впишите после каждой команды "sleep(1);" - команду остановки программы на 1 секунду, и понажимайте "Обновить" в браузере. Во втором случае вы это сразу и увидите.

    Чтобы решить проблему, нужно исключить опасный момент. Другими словами надо заблокировать доступ к файлу счетчика, чтобы все другие параллельно запущенные скрипты, приостановили свою работу. Делается это с помощью flock, который блокирует доступ из других PHP-скриптов (но не из других процессов ОС). Другие скрипты при попытке открыть файл остановятся и будут ждать снятия блокировки.

    <? // верхняя часть страницы // код счетчика: $f2=fopen("counter.txt","r"); // чтобы файл заблокировать, его надо открыть // открыли файл на чтение flock($f2,2); // заблокировали файл $counter=file("counter.txt"); // прочитали файл в массив $counter $f=fopen("counter.txt","w+"); // открыли файл на запись fputs($f,$counter[0]+1); // записали "число + 1" fclose($f); // закрыли файл echo $counter[0]+1; // вывели число на экран flock($f2,3); // сняли блокировку (при закрытии // снимается автоматически) fclose($f2); // и закрыли файл (при выходе // закрывается автоматически) // нижняя часть страницы ?>



    Программу с блокировкой можно было бы написать и в более красим (коротком) виде, но и такой вариант сойдет. Цифры "2" и "3" в функции flock обозначают следующее:

    flock (дексриптор файла, режим)

    режим:

    1 - другие процессы могут отрыть только в режиме чтения
    2 - другие процессы ничего не могут
    3 - снять блокировку

    Итак, на простейшем примере (проще придумать трудно) показаны проблемы параллельного запуска скриптов.


    Источник: www.php.spb.ru

    Ссылки по теме
    Открытие файлов и внешние данные. Потенциальная уязвимость php-скриптов
    Приемы безопасного программирования веб-приложений на PHP
    Пишем PHP код, устойчивый к ошибкам
    Полезные скрипты на PHP
    Обработчик ошибок
    Полезные функции для работы с файловой системой
    Оптимизация программ на PHP
     

     
    Интересное в сети
     
    10 новых программ
    CodeLobster PHP Edition 3.7.2
    WinToFlash 0.7.0008
    Free Video to Flash Converter 4.7.24
    Total Commander v7.55
    aTunes 2.0.1
    Process Explorer v12.04
    Backup42 v3.0
    Predator 2.0.1
    FastStone Image Viewer 4.1
    Process Lasso 3.70.4
    FastStone Image Viewer 4.0
    Xion Audio Player 1.0.125
    Notepad GNU v.2.2.8.7.7
    K-Lite Codec Pack 5.3.0 Full


    Наши сервисы
    Рассылка новостей. Подпишитесь на рассылку сейчас и вы всегда будете в курсе последних событий в мире информационных технологий.
    Новостные информеры. Поставьте наши информеры к себе и у вас на сайте появится дополнительный постоянно обновляемый раздел.
    Добавление статей. Если вы являетесь автором статьи или обзора на тему ИТ присылайте материал нам, мы с удовольствием опубликуем его у себя на сайте.
    Реклама на сайте. Размещая рекламу у нас, вы получите новых посетителей, которые могут стать вашими клиентами.
     
    Это интересно
     

    Copyright © CompDoc.Ru
    При цитировании и перепечатке ссылка на www.compdoc.ru обязательна. Карта сайта.