php - 在 php 中获取锁的最佳方法

标签 php locking apc

我正在尝试更新 APC 中的一个变量,并且会有很多进程尝试这样做。

APC 不提供锁定功能,所以我正在考虑使用其他机制...目前我发现的是 mysql 的 GET_LOCK() 和 php 的 flock()。还有什么值得考虑的吗?

更新:我找到了 sem_acquire,但它似乎是一个阻塞锁。

最佳答案

/*
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
    }
};

关于php - 在 php 中获取锁的最佳方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/325806/

相关文章:

php - 如何让DOMPDF逐步支持unicode字体?

sql - 关于SQL Server锁定机制

java - 当应用程序意外退出时处理文件锁定

php - 禁用 APC 调试?

PHP mysql子查询过滤

php - 使用 register_shutdown_function() 处理 PHP 中的 fatal error

php - 如何获取 MongoDB PHP 中的特定字段?

c# - 字典和锁 C# 的奇怪问题

没有 APC 的共享主机上的 Symfony2 - 太慢了

centos - yum 找不到 php-apc