Will flock'ed file be unlocked when the proces

2020-02-27 05:50发布

Following this answer to limit only one instance of a php script running:

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

?>

My question is, will the flock'ed one.txt file be unlock if the process die in the middle of do_something_lengthy(), i.e. before calling flock($fp, LOCK_UN)?

标签: php centos
3条回答
狗以群分
2楼-- · 2020-02-27 06:14

I made this little script to test it out

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();
}

and for me it it took the OS to unlock the file about 2-5 seconds after the script finished executing if it does not throw any Exception, and up to 2-5 seconds after the script stopped because of the thrown Exception.

Keep in mind that as of php 5.3.2 fclose($fh) will not unlock the file, and the file will remain locked unless you unlock it with php or you will have to wait for the OS to unlock it, which might never happen if there is some bug (this happened to me)

To unlock the file:

flock($fh,LOCK_UN);

To close the file handle (will be called automatically when the script finishes executing)

fclose($fh);

Locking the file without the LOCK_NB will cause the script to wait for the file to get unlocked.

查看更多
趁早两清
3楼-- · 2020-02-27 06:19

The lock is released automatically when the script finishes. However, you should release it manually and not rely on automatic failure to happen. Better to catch any exception, handle it, and release the lock. See the offical docs - http://php.net/manual/en/function.flock.php

查看更多
smile是对你的礼貌
4楼-- · 2020-02-27 06:24

According to the manual page of flock() that PHP uses internally, a lock is released when either flock() is called with LOCK_UN or when the descriptor is closed using fclose().

Upon script termination, either PHP or the OS will close the open file descriptors, thereby releasing the locks you may have.

Because of said behaviour this commit (5.3) and this one (5.2) was made to no longer do the unlocking in PHP itself.

查看更多
登录 后发表回答