Функция flock возвращает истинное значение, если блокировка файла была успешно выполнена. В противном случае возвращается ложное значение. Иногда вызов функции flock приостанавливает выполнение программы до момента снятия других блокировок. Ниже мы остановимся на этом более подробно. Директива use Fcntl qw(; flock) позволяет использовать символические имена вместо трудно запоминаемых цифр при определении типа блокировки.
У функции flock предусмотрены два параметра дескриптор файла и тип блокировки, как показано ниже.
С механизмом совещательной блокировки вы должны быть уже хорошо знакомы. Вспомните, как работает светофор на перекрестке. Красный сигнал светофора запрещает движение транспорта и таким образом препятствует движению машин в пересекающихся направлениях. Но регулировка с помощью светофора работает только тогда, когда все водители строго соблюдают правила дорожного движения. То же самое можно сказать и о механизме блокировки файлов. Любая программа, в которой не исключена возможность доступа к файлам одновременно с другими программами, должна использовать функцию flock для предотвращения нежелательных последствий. Следовательно, механизм совещательной блокировки не препятствует доступу нескольких программ к файлу, а предотвращает только возможность получения права доступа к файлу.
Для блокировки файлов в системах UNIX и Windows NT используется функция Perl flock, в которой реализован так называемый совещательный механизм блокировки. Это означает, что любая программа, которая хочет записать что-либо в файл, должна перед этим вызвать функцию flock и убедиться, что никакая другая программа в данный момент времени ничего не пишет в этот же файл. Естественно, при желании любая программа сможет в любой момент записать данные в файл, не прибегая к средствам блокировки. В этом заключается отличие совещательного механизма блокировки от принудительного.
Блокировка в UNIX и Windows NT
Блокировка файлов вызывает сразу несколько проблем, причем основная из них связана с тем, что в разных файловых и операционных системах используются разные механизмы блокировки. Поэтому в следующих разделах мы расскажем о том, как преодолеть все эти проблемы.
Как мы уже видели, одновременная запись данных в один и тот же файл несколькими программами весьма опасная вещь. Однако это совсем не означает, что подобное невозможно. Процесс одновременной записи в файл синхронизируется механизмом, называемым блокировкой. Таким образом, блокировка файлов предотвращает одновременную запись в файл со стороны нескольких программ в один и тот же момент времени,
Описанная выше работа программы в многозадачной среде чем-то напоминает гонки "Формулы 1". Отлаживать многозадачные и многопоточные приложения очень сложно, поскольку работа таких программ зависит как от количества запушенных копий, так и от многих других факторов. Поэтому ошибки в многопоточных программах не всегда очевидны и их очень трудно выявить и локализовать.
На самом деле проблема гораздо глубже, чем мы только что ее описали. Приведенный выше пример был явно упрощен. Мы не учли тот факт, что функция writedata() не может мгновенно открыть файл и записать в него данные. В многозадачных операционных системах ядро обычно прерывает выполнение программы в середине цикла записи и отдает управление другому процессу. По прошествии нескольких десятков миллисекунд (но не мгновенно!) управление снова возвращается программе, которая записывала данные на диск. Таким образом, возможна ситуация, когда обе программы одновременно попытаются записать разные данные в один и тот же файл. Все это может привести к тому, что часть данных будет испорчена или структура файла будет полностью нарушена.
Когда же копия программы второго пользователя "добирается" до пятого шага, она "затирает" данные, записанные первым пользователем. Таким образом, в окончательном варианте базы данных на диске будет присутствовать запись "Юрий 555-6611", но не будет записи "Дмитрий 555-1212", что является очевидной ошибкой.
Ошибка здесь вот в чем: данные, которые читает второй пользователь на третьем шаге, не содержат записи "Дмитрий 555-1212", поскольку первый пользователь еще не успел ее добавить в файл. Таким образом, второй пользователь добавляет запись "Юрий 555-6611" в массив. @PH0NEL, а в это время первый пользователь записывает в файл базы данных содержимое массива @PHONEL, в котором уже есть запись "Дмитрий 555-1212".
С точки зрения второго пользователя, данные читаются на третьем шаге, новая запись "Юрий 555-6611" добавляется в массив @PHONEL на четвертом шаге, а на пятом шаге содержимое массива @PHONEL записывается в файл базы данных.
С точки зрения первого пользователя, данные читаются на втором шаге, новая запись "Дмитрий 555-1212" добавляется в массив @PHONEL на третьем шаге, а на четвертом шаге содержимое массива @PHONEL записывается в файл базы данных.
Вроде бы все выглядит внешне безобидно, не правда ли? Все так, только проблемы начинаются, когда два или несколько человек одновременно запустят вашу программу на выполнение и попытаются добавить в файл новые записи. При этом программа напрочь перестает работать. Ниже приведена диаграмма выполнения программы двумя пользователями, причем второй пользователь начал свою работу сразу после первого. Проанализируйте ее внимательно.
А теперь предположим, что вашей программе для работы необходимы данные, хранящиеся, например, в текстовом файле, который был описан выше. Тип файла данных здесь не играет особой роли, поскольку все сказанное ниже можно применить к любому типу баз данных. Рассмотрим приведенный ниже фрагмент кода, в котором используются функции, описанные в предыдущем разделе.
Представьте себе, что вы написали на Perl замечательную программу, которой будут пользоваться многие и многие люди. Независимо от того, в какой операционной системе вы планируете ее эксплуатировать (UNIX, Windows NT или даже Windows 9x), возможны ситуации, когда несколько человек попытаются одновременно запустить вашу программу. А если вы предполагаете поместить программу на Web-сервер, она может запускаться так часто, что в памяти вообще одновременно будет находиться несколько копий программы.
Блокировка данных
Отправить форму поиска
Введите условия поиска
Блокировка данных - HTML, CSS, JavaScript, Perl, PHP, MySQL: Weblibrary.biz
Комментариев нет:
Отправить комментарий