Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

best way to obtain a lock in php

Tags:

php

locking

apc

I'm trying to update a variable in APC, and will be many processes trying to do that.

APC doesn't provide locking functionality, so I'm considering using other mechanisms... what I've found so far is mysql's GET_LOCK(), and php's flock(). Anything else worth considering?

Update: I've found sem_acquire, but it seems to be a blocking lock.

like image 250
tpk Avatar asked Nov 28 '08 13:11

tpk


People also ask

What is file locking in php?

File locking is an important task. It restricts other users from changing a specific file. It allows only one user at a time to access or modify it. PHP provides the flock() method for portable advisory file locking. This was introduced with PHP version 4.0.

Which of the following PHP functions is used to make a user locked out from a website?

". lock"); if (! tryLock()) die("Already running.

What is the use of flock function in php?

flock() allows you to perform a simple reader/writer model which can be used on virtually every platform (including most Unix derivatives and even Windows). The lock is released also by fclose(), or when stream is garbage collected.


1 Answers

/*
CLASS ExclusiveLock
Description
==================================================================
This is a pseudo implementation of mutex since php does not have
any thread synchronization objects
This class uses flock() as a base to provide locking functionality.
Lock will be released in following cases
1 - user calls unlock
2 - when this lock object gets deleted
3 - when request or script ends
==================================================================
Usage:

//get the lock
$lock = new ExclusiveLock( "mylock" );

//lock
if( $lock->lock( ) == FALSE )
    error("Locking failed");
//--
//Do your work here
//--

//unlock
$lock->unlock();
===================================================================
*/
class ExclusiveLock
{
    protected $key   = null;  //user given value
    protected $file  = null;  //resource to lock
    protected $own   = FALSE; //have we locked resource

    function __construct( $key ) 
    {
        $this->key = $key;
        //create a new resource or get exisitng with same key
        $this->file = fopen("$key.lockfile", 'w+');
    }


    function __destruct() 
    {
        if( $this->own == TRUE )
            $this->unlock( );
    }


    function lock( ) 
    {
        if( !flock($this->file, LOCK_EX | LOCK_NB)) 
        { //failed
            $key = $this->key;
            error_log("ExclusiveLock::acquire_lock FAILED to acquire lock [$key]");
            return FALSE;
        }
        ftruncate($this->file, 0); // truncate file
        //write something to just help debugging
        fwrite( $this->file, "Locked\n");
        fflush( $this->file );

        $this->own = TRUE;
        return TRUE; // success
    }


    function unlock( ) 
    {
        $key = $this->key;
        if( $this->own == TRUE ) 
        {
            if( !flock($this->file, LOCK_UN) )
            { //failed
                error_log("ExclusiveLock::lock FAILED to release lock [$key]");
                return FALSE;
            }
            ftruncate($this->file, 0); // truncate file
            //write something to just help debugging
            fwrite( $this->file, "Unlocked\n");
            fflush( $this->file );
            $this->own = FALSE;
        }
        else
        {
            error_log("ExclusiveLock::unlock called on [$key] but its not acquired by caller");
        }
        return TRUE; // success
    }
};
like image 192
harry Avatar answered Oct 19 '22 22:10

harry