標籤:style blog http color os io ar for art
<?php/** * 基於redis的分布式鎖 * * 參考開原始碼: * http://nleach.com/post/31299575840/redis-mutex-in-php * * https://gist.github.com/nickyleach/3694555 */pc_base::load_sys_class(‘cache_redis‘, ‘‘, 0);class dist_key_redis { //鎖的逾時時間 const TIMEOUT = 20; const SLEEP = 100000; /** * Stores the expire time of the currently held lock * 當前鎖的到期時間 * @var int */ protected static $expire; public static function getRedis() { return new cache_redis(); } /** * Gets a lock or waits for it to become available * 獲得鎖,如果鎖被佔用,阻塞,直到獲得鎖或者逾時 * * 如果$timeout參數為0,則立即返回鎖。 * * @param string $key * @param int $timeout Time to wait for the key (seconds) * @return boolean 成功,true;失敗,false */ public static function lock($key, $timeout = null){ if(!$key) { return false; } $start = time(); $redis = self::getRedis(); do{ self::$expire = self::timeout(); if($acquired = ($redis->setnx("Lock:{$key}", self::$expire))) { break; } if($acquired = (self::recover($key))) { break; } if($timeout === 0) { //如果逾時時間為0,即為 break; } usleep(self::SLEEP); } while(!is_numeric($timeout) || time() < $start + $timeout); if(!$acquired) { //逾時 return false; } return true; } /** * Releases the lock * 釋放鎖 * @param mixed $key Item to lock * @throws LockException If the key is invalid */ public static function release($key){ if(!$key) { return false; } $redis = self::getRedis(); // Only release the lock if it hasn‘t expired if(self::$expire > time()) { $redis->del("Lock:{$key}"); } } /** * Generates an expire time based on the current time * @return int timeout */ protected static function timeout(){ return (int) (time() + self::TIMEOUT + 1); } /** * Recover an abandoned lock * @param mixed $key Item to lock * @return bool Was the lock acquired? */ protected static function recover($key){ $redis = self::getRedis(); if(($lockTimeout = $redis->get("Lock:{$key}")) > time()) { //鎖還沒有到期 return false; } $timeout = self::timeout(); $currentTimeout = $redis->getset("Lock:{$key}", $timeout); if($currentTimeout != $lockTimeout) { return false; } self::$expire = $timeout; return true; }}?>
基於redis的分布式鎖