Today's Question:  What does your personal desk look like?        GIVE A SHOUT

PHP advisory file lock : flock

  sonic0002        2013-04-23 11:42:48       8,136        0    

When we process a file in PHP, we may often need to acquire a lock so that other scripts cannot edit the same file at the same time. There is a flock() function in PHP which can help us lock the file we want to process. But there is one issue we should take care.

Recently, ffb encountered one issue while he was trying to lock a file handle. The codes are below:

  1. $filename = "/tmp/lock.txt";  
  2.   
  3. $fp = fopen($filename"r+");  
  4. if (!$fp) {  
  5.     die("open failed.");  
  6. }  
  7.   
  8. if (flock($fp, LOCK_EX)) {  // Exclusive lock
  9.     sleep(20);  
  10.     $count = (int)fgets($fp);  
  11.     $count += 1;  
  12.     fseek($fp, 0);  
  13.     fwrite($fp, (string)$count);  
  14.     fflush($fp);            // flush output before releasing the lock  
  15.     flock($fp, LOCK_UN);    // Release lock
  16. else {  
  17.     echo "Couldn't get the lock!";  
  18. }  
  19.   
  20. fclose($fp);  
  21. ?> 

In the 20s while this script is sleeping, he was tying to edit the tmp/lock.txt file using vi, he found he could successfully edit the file and save the file without waiting for the first script to complete. After checking the documentation, there is one concept called advisory locking mechanism which means all accessing programs have to use the same way of locking or it will not work.

Then creating the second script:

  1.     $count = (int)fgets($fp);  
  2.     echo $count;  
  3.     $count += 1;  
  4.     flock($fp, LOCK_UN);    // Release lock
  5. else {  
  6.     echo "Couldn't get the lock!";  
  7. }  
  8.   
  9. fclose($fp);  
  10. ?>

He tried to run the second the script while the first one was running, the second one would wait for the first one to complete. Then what does the same way of locking mean?

Here are some testings:

Group A:

1. Change the parameter of flock() to LOCK_SH in script 1 and keep the script 2 as unchanged, the result is the block is successful since script 2 tries to acquire the lock and the lock will not be shared. So it has to wait for the script 1 to complete.

2. Change parameter of flock() to LOCK_SH in both script 1 and script 2, the result is script 2 can return result without waiting for script 1 to complete.

Group B:

1. Change parameter of flock() in script 2 to LOCK_SH and keep script 1 as unchanged, blocking is successful as script one acquires the lock and it cannot be shared by script 2.

Comparison group:

1. Change the parameter of fopen() to "r" in script 2, run Group A tests, the result is the same

2. Change the parameter of fopen() to "w+" in both script 1 and script 2, run Group A tests, results is the same

3. Change the parameter of fopen() to "w+" in both script 1 and script 2, run Group B tests, result is the same

So the locking has some relationship with LOCK_* parameter, but it will not depend on the way files is opened. The reason why vi can be used to edit the file is because the lock is thread level.

PHP  FLOCK()  ADVISORY LOCKING 

Share on Facebook  Share on Twitter  Share on Weibo  Share on Reddit 

  RELATED


  0 COMMENT


No comment for this article.