| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Perl: разработка для Web > Одновременная запись в один файл |
| Автор: Dimoon 2.5.2006, 00:32 |
| Скажите пожалуйста, что будет, если два пользователя моей гостевой книги одновременно добавят сообщение? Где то читал, что от этого надо предохраняться. А как именно? Как запретить пользователю доступ к файлу на запись, если в этот момент кто то ее производит? Большое спасибо! |
| Автор: Wilmer 2.5.2006, 15:35 |
| Нужно было попробывать самому, что из этого получиться. Скорее всего одна запись добавиться, а у второй будет ошибка. Либо одна запись добавится, а вторая поверх нее запишется. Блокировку можно установить функцией flock. Вариант 1. Для каждого сообщения создавать свой файл. Другим скриптом собирать все записи в один файл. Т.е. каждый открывать, читать, записывать в основной, удалять. Такой скрипт лучше всего запускать через какое-то промежуток время. Вариант 2. Использовать БД и не мучаться с файлами. Хотя для гостевой использовать БД, не лучший вариант. Вариант 3. Использовать блокировку файла. Добавлено @ 15:39 Если я не ошибаюсь, почти в каждой книге в разделе по работе с файлами описана блокировка. Лучше всего приобрести книгу. |
| Автор: GoodBoy 3.5.2006, 09:20 |
не все ОС поддерживают эту функцию! |
| Автор: sharq 3.5.2006, 12:10 |
поэтому можно использовать файлы-семафоры. |
| Автор: Dimoon 3.5.2006, 15:44 |
| Вот что я нашел, работает под любую OC: Описание Суть метода простая - перед тем, как "занять" файл данных, скрипт создает этот временный файл, а после освобождения - удаляет. Таким образом, наличие этого временного файла означает, что файл данных занят. Другой экземпляр скрипта перед записью проверяет наличие временного файла и, если он есть, дожидается его удаления первым экземпляром, и только затем начинает работу с файлом данных. Имя для временного файла может быть любым - главное, чтобы для блокировки разных файлов данных разными скриптами использовались разные имена. ######################################### $lockfile="data.tmp"; #Имя временного файла блокировки $count=50; $interval=0.05; #Кол-во попыток и интервал между ними if (-e $lockfile) { #Если временный файл есть, ждем его удаления другим процессом while (($count>0)&&(-e $lockfile)) { sleep $interval; $count-=1; }; }; if ($count==0){ #Здесь размещается код обработки непредвиденной ошибки }; open TF,">$lockfile"; #Создаем временный файл close TF; #... #Здесь размещается собственно код работы с файлом данных #... unlink $lockfile; #Удаляем временный файл Этот участок скрипта проверяет, существует ли временный файл. Если он существует, то производится ($count) проверок его существования через интервалы ($interval) секунд (значения 50 и 0.05 можно заменить своими; предполагается, что время ($count*$interval) более чем достаточное, чтобы другой процесс завершил работу с файлом данных). Как только временный файл будет удален другим процессом, произойдет выход из цикла; далее скрипт создает свой временный файл, осущетсвляет работу с файлом данных и удаляет временный файл. Автор: Андрей Черный |
| Автор: Wilmer 3.5.2006, 16:19 |
| Мне кажется, что вернее будет если размещать функции для работы с файлом до его закрытия. Иначе ничего интересного не будет. Потом, как я знаю, если делается закрытие файла, то блокировка автоматически снимается. Лучше блокировку снимать до закрытия файла. Если я ошибаюсь, поправьте меня. |
| Автор: Dimoon 3.5.2006, 18:51 |
| Подскажите пожалуйста, как выглядит "код обработки непредвиденной ошибки" |
| Автор: sharq 4.5.2006, 10:14 | ||||
| Dimoon, смотря в каком контексте, привиди пример. Обычно ошибку можно поймать через проверку результата выполнения команды (в таком случае ошибка обычно содержится в $!)
или через блок eval (ошибка содержится в переменной $@).
|