2012-05-21 19 views

回答

0

可以「鎖定」使用如下代碼設置前的關鍵。

此代碼假定您有儀器換PHP庫:

http://code.google.com/p/instrumentation-for-php

註釋掉儀器行,如果你不想使用它

function acquire_mutex_or_wait($key,$memcache = false) { 
    Instrumentation::get_instance()->increment('memcache_mutex_requests', 1); 
    if($memcache === false) { 
      #bring in memcache from global scope 
      global $memcache; 
    } 
    #prepend LOCK:: to the key to designate the new key as a lock for the given key 
    $key = "LOCK::$key"; 

    #generate a random number for the lock (see below) 
    $lockval = mt_rand(1,2^31); 

    #add is SUPPOSED to be atomic, but it isn't really with multiple servers 
    #to protect against two connections getting the mutex we initialize it 
    #to a random value and check the value after setting. If we didn't 
    #really aquire the mutex, the value we get will be different from the 
    #value we set 
    $got_lock = $memcache->add($key, $lockval); 
    if($got_lock) { 
      $got_lock = $memcache->get($key); 
      $got_lock = $got_lock === $lockval; 
      if($got_lock) return true; 
    } 

    #the mutex was not acquired. we must wait for it to be released 
    $sleep_time = .01; #initial sleep time 
    $sleep_time_increment = .05; 
    $max_sleep_time=1; #maximum number of seconds to sleep between checking locks 
    Instrumentation::get_instance()->timer(); 
    Instrumentation::get_instance()->increment('memcache_mutex_waits', 1); 
    while(1) { 
      usleep($sleep_time * 1000000); 
      $sleep_time += $sleep_time_increment; 
      if($sleep_time > $max_sleep_time) $sleep_time = $max_sleep_time; 
      $exists = $memcache->get($key); 
      if(!$exists) break; #mutex has been released 
    } 
    Instrumentation::get_instance()->increment('memcache_mutex_wait_time', Instrumentation::get_instance()->timer()); 
    return false; 
} 

#NOTE - only the connection that acquired a mutex should release it. there is no 
#protection to ensure this is the case 
function release_mutex($key, $memcache = false) { 
    if($memcache === false) { 
      #bring in memcache from global scope 
      global $memcache; 
    } 

    $key = "LOCK::$key"; 
    return($memcache->delete($key)); 
} 
相關問題