IMHO.WS

IMHO.WS (http://www.imho.ws/index.php)
-   Веб-программирование (http://www.imho.ws/forumdisplay.php?f=29)
-   -   защита от одновременной записи в файл (http://www.imho.ws/showthread.php?t=43136)

sanchos 11.11.2003 17:13

защита от одновременной записи в файл
 
Напомните мне, плиз, как сделать сабж.
Есть файлик, который очень часто читается и в который не реже все пишется... так вот очень не хотелось бы потерять данные из него.
Помню что-то про flock(), но не помню что и как :(
Заранее сенькс :)

Stasik 12.11.2003 17:23

$fp = fopen("/tmp/lock.txt", "w+");

if (flock($fp, LOCK_EX)) { // do an exclusive lock
fwrite($fp, "Write something here\n");
flock($fp, LOCK_UN); // release the lock
} else {
echo "Couldn't lock the file !";
}

fclose($fp);


выдрал из мануала

helldomain 12.11.2003 17:54

Wse hotel zadat wopros! Dannij primer ispolzowaniya flock(), esli ukazannij fail uje blokirowann, on zastawlyaet process/thread jdat poka ekskliuziwnoe blokirowanie ne pereidet k nemu ili srazu wibrasiwaet error.

Stasik 13.11.2003 00:07

if(flock($fp, LOCK_EX)) imho он сразу отпустит

sanchos 18.11.2003 10:30

Stasik
Значит, как я понимаю, просто пишем так:
PHP код:

flock($fpLOCK_EX)
fwrite($fp"data");
flock($fpLOCK_UN); 

Во время записи файл заблокирован. Если в это время производится параллельная запись, то она будлет поставлена в очередь или будет проигнорирована?

f00rd 18.11.2003 11:44

При использовании flock лучше всего использовать так называемые семафоры, например:

#!/usr/bin/perl -w
use Fcntl qw(:flock);

$sem = "/tmp/sem.sem";

sub get_lock {
open(SEM, ">$sem") || die "Невозможно создать семафор: $!";
flock(SEM, LOCK_EX) || die "Невозможно заблокировать семафор: $!"
}
sub release_lock {
close(SEM);
}

get_lock(); # ожидает бесконечно долго, до снятия защиты...

...
#Операции
...

release_lock()

sanchos 18.11.2003 11:45

мне б на пхп :)

f00rd 18.11.2003 11:46

sanchos
тогда не знаю :rolleyes:

sanchos 18.11.2003 13:11

все равно пасиб ;)

sanchos 24.11.2003 12:45

Хм. все равно обнулил :(
Есть какой-нить другой способ защиты?

Stasik 24.11.2003 17:14

mysql? ;)

helldomain 24.11.2003 17:27

Imeetsya w widu hranenie dannih w mysql ili sinhra failowih deskriptorow cherez mysql (eto kak togda???)?.

Stasik 25.11.2003 01:57

хранение данных в mysql

helldomain 25.11.2003 03:11

Nu da, soglasen, mysql wse sinhroniziruet ot i do (nu a kak eshe), no est takie weschi, kotorie w mysql ne polojish (ne tehnicheski daje, a po logike proekta).

sanchos 25.11.2003 09:12

Stasik
А если нет поддержки MySQL? Нужно средствами пхп... :(

helldomain 25.11.2003 09:41

Da, widat dostali uje stasika ;-)o.

WMRomik 25.11.2003 10:15

Вот чего нашлось туточки:

http://wmasteram.h10.ru/articles/php...l=counter.html
===========================
Наиболее интересным моментом в работе счетчика является защита данных от "порчи" при применении "многопоточных" интернет-серверов. В документации по PHP ясно дается понять, что применять "штатную" функцию flock() для блокирования лог файлов нецелесообразно. Поэтому пришлось выдумать свою, пускай и несколько наивную, схему блокировки. Смысл ее состоит в следующем: для каждого лог-файла, для которого существует возможность одновременной записи и чтения информации, до записи создается id файл . После записи он уничтожается. Если "второй" процесс заметил существование такого файла, то он ждет 1с на его уничтожение.

Подобное реализуется в следующей функции:

function is_month_lock() <--- есть есть id, файл возвращает 1, иначе - 0
function month_lock() <--- Создает ид файл
function month_unlock() <--- Уничтожает id файл
function write_m($str)
{
$i=0;
$write_ok=0;
while ($i<20 && $write_ok==0) <--- Всего 20 циклов ожидания уничтожения файла
{
if (!$this->is_month_lock())
{ $this->month_lock(); $lf=$GLOBALS['counter_log_month']; $fp = fopen ($lf,"a+");
fwrite($fp,$str);
fflush($fp);
fclose($fp);
$this->month_unlock();
$write_ok=1;
}
else
{
usleep(50000); <--- Один цикл ожидания
$i++;
}
}

if ($write_ok!=1)$this->month_unlock(); <--- Защита от "сбойного" поведения PHP. Для спокойствия (на медленных серверах) можете увеличить количество периодов до 100 шт.
return $write_ok;
}
====================================
Сам ничего не проверял.

sanchos 25.11.2003 13:12

WMRomik
Вот, пасиб :) Буду разбираться. Идею саму понял, может сам чего забацаю :)


Часовой пояс GMT +4, время: 01:48.

Powered by vBulletin® Version 3.8.5
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.