Jump to content

File locking, flock()...


enveetee

Recommended Posts

Hi

 

I can't get flock() to work, it seems to be such a simple function but I am stumped.

 

What I think I know...

 

1. There is a blocking and advisory mode (blocking, waits for a lock whereas advisory lets you know if a lock was succesfully applied)

 

2. Some UNIX systems do not support blocking

 

3 Open the file with fopen (+r), apply flock() and if the lock is successful, write to the file.

 

I have my script 

 
$bse = fopen($filename, "r+"); //Open for reading and writing; place the file pointer at the beginning of the file. File must exist
    if (!flock($bse, LOCK_EX))
        {
            echo "Waiting for lock on ".$filename;
        }

 

 

I am using this method to open a file, get a serial number, increment the serial number, write it back to the file then add the serial number to a MySQL table with UNIQUE set on the serial number field. I to this to test if the serial number has been added before and thus test the file locking.

 

It does not work, I get duplicate serial numbers trying to be added.

 

 

 

Anyone got any pointers as to what I may be doing wrong

Link to comment
Share on other sites

The basic gist of locking goes like this:

$bse = fopen($filename, 'r+');
if (flock($bse, LOCK_EX)){
  $value = fgets($bse); //Read the value
  rewind($bse); //Reset file pointer
  fwrite($bse, $value+1); //Write back new value
  flock($bse, LOCK_UN);  //Release lock
}
fclose($bse);
flock will wait until it either successfully obtains a lock, or something interrupts it and prevents it from doing so.

 

If it is successful, it returns true which indicates you can go ahead and do what you want with the file.

If it fails, it will return false which means you should not do anything with the file and just close it.

Link to comment
Share on other sites

You'd test it by just trying to run two instances of a script concurrently.

 

For example:

<?php

$filename = isset($argv[1])?$argv[1]:'lockfile.txt';

$fp = fopen($filename, 'r+');
if (!$fp){
    die('Could not open file.  Create it first.');
}

echo 'Attempting to acquire lock'.PHP_EOL;
if (flock($fp, LOCK_EX)){
    echo 'Lock has been acquired'.PHP_EOL;
    $value = trim(fgets($fp));
    rewind($fp);
    fwrite($fp, $value+1);
    echo 'Read value '.$value.'; Incremented value to '.($value+1).' and wrote it back'.PHP_EOL;
    echo 'Pausing for a while for testing'.PHP_EOL;
    sleep(10);
    fflush($fp);
    flock($fp, LOCK_UN);
    echo 'Lock has now been released'.PHP_EOL;
}
fclose($fp);
echo 'Finished'.PHP_EOL;
Open a couple of terminal windows and run separate copies of the script. One of them will get the lock and then pause, the other will wait until the first completes.
Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.