Будет ли файл flock'ed разблокирован, когда процесс неожиданно завершится?

После этого ответа ограничиваем только один экземпляр скрипта php:

<?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) ?

Согласно странице руководства flock() которую использует PHP внутри, блокировка LOCK_UN когда либо flock() вызывается с LOCK_UN либо когда дескриптор закрыт с помощью fclose() .

После завершения сценария PHP или ОС закрывают дескрипторы открытых файлов, тем самым освобождая блокировки, которые у вас могут быть.

Из-за указанного поведения это commit (5.3) и этот (5.2) было сделано, чтобы больше не делать разблокировку в самом PHP.

Я сделал этот маленький скрипт, чтобы проверить его

 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 секунд после завершения скрипта, если он не выбрасывает исключение и до 2-5 секунд после остановки скрипта из-за брошенного исключения.

Имейте в виду, что с php 5.3.2 fclose($fh) не разблокирует файл, и файл останется заблокированным, если вы не разблокируете его с помощью php, или вам придется дождаться, когда ОС разблокирует его, что, возможно, никогда не произойдет если есть какая-то ошибка (это случилось со мной)

Чтобы разблокировать файл:

 flock($fh,LOCK_UN); 

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

 fclose($fh); 

Блокировка файла без LOCK_NB заставит скрипт ждать, пока файл будет разблокирован.

Блокировка запускается автоматически, когда скрипт заканчивается. Однако вы должны выпустить его вручную и не полагаться на автоматический сбой. Лучше поймать любое исключение, обработать его и отпустить блокировку. См. Официальные документы – http://php.net/manual/en/function.flock.php