当进程意外死亡时,flock'ed文件会被解锁吗?

时间:2012-11-23 01:58:12

标签: php centos

遵循此answer仅限制运行的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中间死亡,即在调用do_something_lengthy()之前,flock($fp, LOCK_UN)'ed one.txt文件是否会被解锁?

3 个答案:

答案 0 :(得分:13)

根据PHP内部使用的flock()手册页,当使用flock()调用LOCK_UN或使用fclose()关闭描述符时,会释放锁定

脚本终止后,PHP或操作系统将关闭打开的文件描述符,从而释放您可能拥有的锁。

由于上述行为this commit(5.3)和this one(5.2)已经不再使用PHP本身进行解锁。

答案 1 :(得分:5)

我制作了这个小脚本来测试它

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的情况下锁定文件将导致脚本等待文件解锁。

答案 2 :(得分:2)

脚本完成后会自动释放锁定。但是,您应该手动释放它,而不是依赖于自动故障发生。最好捕获任何异常,处理它并释放锁。请参阅官方文档 - http://php.net/manual/en/function.flock.php