Personal penis extender™. Extending penis since 1998. эбаут  •  скачать  •  карта сайта  •  почта    
SPECTATOR: OUTDATED
Home / технологии / php / Как мы побороли flock

Как мы побороли flock

  // 23 января 2004 года

Дано: файл, в который часто пишется информация и часто из него считывается. Например, простой текстовый счетчик на страницу.

Проблема: рано или поздно, но обязательно случится ситуация, когда одновременно к файлу будет несколько обращений — и на запись и на чтение. И вся информация, натурально, потеряется.

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

В идеале это работает. Но — цитирую документацию по PHP — «flock() will not work on NFS and many other networked file systems. Check your operating system documentation for more details». Если почитать все ту же документацию, то в комментариях пользователей приводится множество способов побороть flock, вплоть до самых экзотичных.

Стоит ли говорить, что у меня ни сам flock, ни другие способы просто не работали?

В конце концов, я набрел в одном англоязычном блоге на интересную фразу как раз по этому поводу: «A file rename operation is guaranteed to be atomic by the operating system, and is very efficient as file functions are always highly optimized».

То есть, rename — это атомарная, сиречь неделимая функция операционной системы. К тому же она очень эффективная, потому что файловые функции всегда хорошо оптимизированы.

Так что я попробовал побороть flock следующим образом: сначала пишем все, что нам нужно, в временный файл (не забудьте выставить правильный chmod на директорию, в которую он будет писаться), а потом просто переименовываем этот файл в тот файл, который нужно. Причем в unix-овых системах старый файл удалять нет необходимости — все будет перезаписано сверху.

Я написал две функции. Первая функция — это функция записи в файл, вторая — чтения из файла. Эти две функции интенсивно работают у меня вот уже больше месяца, и пока не было ни одного сбоя.

Запись в файл:

function S_fw ($COUNT_FILE, $text)
{
$z=rand (0,100000);
$fp = @fopen($COUNT_FILE.".".$z, "wb+");
@fwrite($fp,$text);
@fclose($fp);
if (@rename ($COUNT_FILE.".".$z, $COUNT_FILE)==false)
{
@unlink ($COUNT_FILE);
@rename ($COUNT_FILE.".".$z, $COUNT_FILE);
}
}

Чтение из файла (flock здесь стоит «на всякий случай»):

function S_fr ($COUNT_FILE)
{
clearstatcache();
$fp = @fopen($COUNT_FILE, "rb");
@flock ($fp,LOCK_SH);
$conts=@fread ($fp, filesize ($COUNT_FILE));
@fclose ($fp);
@flock($fp, LOCK_UN);
return $conts;
}

Пользуйтесь на здоровье.

PS. Мне тут подсказывают про функцию tempnam. Использовать ее будет более правильно, чем rand.

PSS. Прислали ссылку на еще один способ, как это можно сделать. Я не проверял.

 

поиск:



 ^  Copyright © 1998-2008 by Дмитрий Смирнов. Перепечатки возможны только с указанием ссылки.
Ручной трубогиб ; верно. Серия Бельвиль, конструктор лего для девочек беспорно. Наслаждение игрой ; mmcis group ; Качественный украинский хостинг с мощными серверами. ; Профессионалы помогут продать акции быстро! ; Дальнобойщики 3 купить ; теория покера скачать