Будет ли файл flock'ed разблокирован, когда процесс неожиданно завершится?
Следуя этому answer, чтобы ограничить только один экземпляр запуска php script:
<?php
$fp = fopen("/tmp/one.txt", "r+");
if (flock($fp, LOCK_EX)) {
//
do_something_lengthy();
//
flock($fp, LOCK_UN);
} else {
echo "Couldn't get the lock!";
}
fclose($fp);
?>
Мой вопрос в том, будет ли разблокирован файл flock
'ed one.txt, если процесс умирает в середине do_something_lengthy()
, то есть перед вызовом flock($fp, LOCK_UN)
?
Ответы
Ответ 1
В соответствии с страницей руководства flock()
, которую использует PHP внутренне, блокировка выдается при вызове flock()
с LOCK_UN
или когда дескриптор закрывается с помощью fclose()
.
После завершения script либо PHP, либо ОС закроют дескрипторы открытого файла, тем самым освободя блокировки, которые у вас могут быть.
Из-за указанного поведения этот коммит (5.3) и этот (5.2) был сделан без более длинная разблокировка в самом PHP.
Ответ 2
Я сделал этот маленький script, чтобы проверить его
header('Content-type:text/plain; charset=utf-8');
$dir = dirname(__FILE__);
$file = $dir.'/testflock.lock';
$fh = fopen($file, 'w+');
$unlocked = flock($fh, LOCK_EX | LOCK_NB);
echo 'Locked: '.$file.' ';var_dump(!$unlocked);echo PHP_EOL;
if($unlocked){
sleep(10);
throw new Exception();
}
и для меня потребовалось, чтобы ОС разблокировала файл примерно через 2-5 секунд после завершения завершенного выполнения script, если он не выбрасывает исключение и до 2-5 секунд после остановки script из-за брошенное исключение.
Имейте в виду, что с php 5.3.2 fclose($fh)
не будет разблокировать файл, и файл останется заблокированным, если вы не разблокируете его с помощью php, или вам придется ждать, пока ОС разблокирует его, что может никогда если есть какая-то ошибка (это случилось со мной)
Чтобы разблокировать файл:
flock($fh,LOCK_UN);
Чтобы закрыть дескриптор файла (будет вызываться автоматически, когда script завершает выполнение)
fclose($fh);
Блокировка файла без LOCK_NB
приведет к тому, что script дождитесь, когда файл будет разблокирован.
Ответ 3
Блокировка открывается автоматически при завершении script. Однако вы должны выпустить его вручную и не полагаться на автоматический сбой. Лучше поймать любое исключение, обработать его и отпустить блокировку. См. Официальные документы - http://php.net/manual/en/function.flock.php