блокировка файла

Статус
В этой теме нельзя размещать новые ответы.

saiman

Новичок
Код:
                $fu = fopen("data/stats/$this->today.dat","a");
                flock($fu, LOCK_EX);
                ftruncate ($fu, 0);
                fseek ($fu, 0);
                fputs($fu,serialize($today_stats[$this->today]));
                fflush ($fu);
                flock($fu, LOCK_UN);
                fclose($fu);
я верно все понял и описал??
если да то от этого толку никакого, ибо может это была и дыра но судя по всему не единственная. так как файл все равно обнуляется!
 

SiMM

Новичок
PHP supports a portable way of locking complete files in an advisory way (which means all accessing programs have to use the same way of locking or it will not work).

flock() is not supported on antiquated filesystems like FAT and its derivates and will therefore always return FALSE under this environments (this is especially true for Windows 98 users).

[m]flock[/m]
 

MiksIr

miksir@home:~$
Автор оригинала: fixxxer
проверй результат flock
А вроде flock по-умолчанию блокирующий.

saiman начни думать, а? Например, что произойдет, если другой скрипт прочитает файл (чтение то ты не блокируешь), когда он обнулен?
 

Pigmeich

Новичок
А вроде flock по-умолчанию блокирующий.
Провалиться он все равно может. Что бы не было "по-умолчанию".

saiman начни думать, а? Например, что произойдет, если другой скрипт прочитает файл (чтение то ты не блокируешь), когда он обнулен?
flock
там про экслюзив говорится.
 

dimagolov

Новичок
здается мне, что засада в том, что flock ничего не может поделать с стуацией, когда fopen уже был сделан с двух скриптов. при этом один обнуляет, а второй читает обнуленное.

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

Pigmeich

Новичок
здается мне, что засада в том, что flock ничего не может поделать с стуацией, когда fopen уже был сделан с двух скриптов. при этом один обнуляет, а второй читает обнуленное.
Потому что, второй flock может не дождатся освобождения ресурса, а тупо вернуть false.

Но главная проблема в промежутке между обрезанием файла и локом. Нужно сначала локать а потом хоть Нюрнбергский процесс устраивать.
 

Фанат

oncle terrible
Команда форума
под конец набежали специалистыыыыы.

-~{}~ 21.11.07 20:32:

MiksIr
LOCK_EX блокирует, как раз, чтение. Насколько я понимаю

-~{}~ 21.11.07 20:38:

saiman
у тебя не винда?
что будет, если написать тестовый скрипт, такой, примерно
PHP:
echo str_pad('',1024);
echo "start<br>\n";
flush();
$f=fopen("ttt.htm","a+");
flock($f,2);
echo "lock<br>\n";
flush();  // worked 
sleep(10);
flock($f,3);
echo "end<br>\n";
и запустить сначала один, а потом в другом окне - второй?
 

MiksIr

miksir@home:~$
Pigmeich, провалится то может и проверять возврат нужно, но в данном случае проблема не в этом.

*****, он не блокирует, он ставит флаг, что блокированно... а значит, если перед чтением этот флаг не проверить, то можно спокойно читать, например, пустой файл. У топикстартера же никаких проверок блокировки перед чтением нет.

Т.е. нужно делать так
open (r+)
flock(LOCK_EX)
read
seek(0)
truncate
write
flock(LOCK_UN)
close
только в этом случае можно гарантировать, что произойдет чтение актуальных данных
 

SiMM

Новичок
> Открыл файл на чтение, прочитал, закрыл.
В это время его открыл другой экземпляр скрипта, который тоже
> Создал темповый файл, и в него записал, закрыл.
> Переименовал темповый в нужный.
В итоге, если речь об append, одна из записей будет потеряна.
 

saiman

Новичок
вот переделал так:
Код:
              $fu = fopen("data.dat","a");
            if (flock($fu, LOCK_EX)) {
                ftruncate ($fu, 0);
                fseek ($fu, 0);
                fwrite($fu,serialize($today_stats[$this->today]));
                fflush ($fu);
                flock($fu, LOCK_UN);
            }
                fclose($fu);
и файл не обнуляется даже при большом количестве траффика.
но в этом случае некоторые записи не дожидаются unlock и просто уходят. тоесть не обнуляются но записываются не все.
 

Фанат

oncle terrible
Команда форума
странно.
я вижу здесь только запись в файл.
а чтения не вижу.

у тебя, по ходу, с логикой совсем проблемы.
 

saiman

Новичок
так причем тут чтение. какое отношение имеет чтение к тому что некоторые пользователи не дожидаются записи. если б дело было в чтении пустого файла то и записывался бы пустой.
 

Фанат

oncle terrible
Команда форума
действительно, при чем тут чтение.
тут пользователи виноваты - не дожидаются.
вот с них тогда и спрашивай
 

saiman

Новичок
а серьезно? есть варианты?

-~{}~ 22.11.07 13:22:

а кто подскажет ?
если не выполняется условие:
if (flock($fu, LOCK_EX)) {

}
пользователь ждет или идет дальше??
 

Nelius

кипарис во дворе
PHP:
function flock_get_contents($filename){

    $return = FALSE;

    if(is_string($filename) && !empty($filename)){
        if(is_readable($filename)){
            if($handle = @fopen($filename, 'r')){
                while(!$return){
                    if(flock($handle, LOCK_SH)){
                        if($return = file_get_contents($filename)){
                            flock($handle, LOCK_UN);
                        }
                    }
                }
                fclose($handle);
            }
        }
    }
    
    return $return;
}
Пример с php.net
Проверяем доступен ли для чтения, пробуем залочить под себя, когда получается делаем что нужно.
Разбирайтесь, все просто на самом деле.
 

Фанат

oncle terrible
Команда форума
а кто подскажет ?
если не выполняется условие:
if (flock($fu, LOCK_EX)) {

}
пользователь ждет или идет дальше??
мля.
я тебе ГОТВЫЙ КОД НАКАТАЛ, для проверки этого!
а ты все тупишь.
чувствую, форум только мешает тебе
 
Статус
В этой теме нельзя размещать новые ответы.
Сверху