Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Will flock'ed file be unlocked when the process die unexpectedly?

Tags:

php

centos

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

like image 655
ohho Avatar asked Nov 23 '12 01:11

ohho


3 Answers

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) were made to no longer do the unlocking in PHP itself.

like image 109
Ja͢ck Avatar answered Oct 19 '22 11:10

Ja͢ck


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.

like image 44
Timo Huovinen Avatar answered Oct 19 '22 11:10

Timo Huovinen


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

like image 23
Kami Avatar answered Oct 19 '22 12:10

Kami