php bir kilit elde etmek için en iyi yolu

7 Cevap php

Ben APC bir değişkeni güncellemeye çalışıyorum, ve bunu yapmak için çalışan birçok süreçler olacaktır.

APC işlevsellik kilitleme sağlamaz, bu yüzden diğer mekanizmaları kullanarak düşünüyor yaşıyorum ... benim bulduğum kadar mysql'in GET_LOCK (), ve PHP sürüsünü () 'dir. Dikkate değer başka bir şey?

Güncelleme: Ben sem_acquire buldum, ama bir engelleme kilidi gibi görünüyor.

7 Cevap

Sistemleri veya MySQL Dosya başvurmadan bunu başarmak için apc_add işlevini kullanabilirsiniz. Değişkeni zaten kayıtlı değilken apc_add sadece başarılı; Böylece, kilitleme mekanizması sağlar. Memcache da bir atom eklenti fonksiyonu içerir ve bu nedenle de bu teknikle kullanılabilen - bilgisayarlar arasında kilitleme bir yöntemdir ki.

Kilit nokta boş bir önbellek anahtarı doldurmak için çalışırken çoklu süreçleri engellemek için ise, neden bir engelleme kilit sahip olmak istemez ki?


  $value = apc_fetch($KEY);

  if ($value === FALSE) {
      shm_acquire($SEMAPHORE);

      $recheck_value = apc_fetch($KEY);
      if ($recheck_value !== FALSE) {
        $new_value = expensive_operation();
        apc_store($KEY, $new_value);
        $value = $new_value;
      } else {
        $value = $recheck_value;
      }

      shm_release($SEMAPHORE);
   }

Önbellek iyi ise, sadece onunla rulo. Hiçbir şey önbellekte varsa, bir kilit almak. Eğer kilidi var bir kere, sen kilit almak için bekleyen iken, önbellek repopulated değil, emin olmak için önbelleği tekrar kontrol etmek gerekir. Önbellek repopulated ise, bu değeri kullanın & Kilidi açmak, aksi takdirde hesaplama yapmak, önbelleği ve doldurmak sonra kilidi bırakın.

Aslında, bu Peter'ın önerisi sonra daha iyi çalışacak görmek için kontrol edin.

http://us2.php.net/flock

özel bir kilidi kullanmak ve onunla rahat eğer, bir 2-3 saniye uyku dosyayı kilitlemek için çalıştı her şeyi koymak. Yapılırsa doğru sitenizin kilitli kaynak değil samething önbelleğe için mücadele komut bir kalabalık ile ilgili bir asmak yaşayacaksınız.

Ben bu bir yıllık olduğunu biliyoruz, ancak bazı PHP kilitlemeyi kendimi araştırma yaparken ben sadece soru tökezledi.

Bu bir çözüm APC kendisi kullanarak mümkün olabileceğini bana oluşur. Bana deli diyebilirsiniz, ama bu uygulanabilir bir yaklaşım olabilir:

function acquire_lock($key, $expire=60) {
    if (is_locked($key)) {
        return null;
    }
    return apc_store($key, true, $expire);
}

function release_lock($key) {
    if (!is_locked($key)) {
        return null;
    }
    return apc_delete($key);
}

function is_locked($key) {
    return apc_fetch($key);
}

// example use
if (acquire_lock("foo")) {
    do_something_that_requires_a_lock();
    release_lock("foo");
}

Pratikte ben sadece varolan APC tuşu, örneğin ile çarpışmayı önlemek için, burada kullanmak için bir anahtar oluşturmak için orada başka bir işlevi atmak olabilir:

function key_for_lock($str) {
    return md5($str."locked");
}

Bu komut ölür veya böyle bir şey varsa sonsuza tutuluyor sizin kilit önlediğinden $expire parametre kullanmak için APC güzel bir özelliktir.

Umarım bu cevap bir yıl sonra burada sendeler herkes için yararlı olduğunu.

Eğer dosya sistemi üzerinde kilit dayandırarak sakıncası yoksa, o zaman 'x' modu ile () Fopen kullanabilirsiniz. İşte bir örnek:

$f = fopen("lockFile.txt", 'x');
if($f) {
    $me = getmypid();
    $now = date('Y-m-d H:i:s');
    fwrite($f, "Locked by $me at $now\n");
    fclose($f);
    doStuffInLock();
    unlink("lockFile.txt"); // unlock        
}
else {
    echo "File is locked: " . get_file_contents("lockFile.txt");
    exit;
}

Www.php.net / fopen görün

Ne buldum, aslında, ben hiç bir kilitleme gerekmez ki ... ne yaratmaya çalışıyorum autoload için tüm class => yol derneklerin bir harita verilmiş, bu takdirde önemli değil bir süreç diğeri veri sonunda yine oraya çünkü, (düzgün kodlu eğer, son derece düşüktür) bulmuştur ne yazar. Peki, çözüm "hayır kilitleri" olduğu ortaya çıktı.

EAccelerator bunun için yöntem vardır; eaccelerator_lock ve eaccelerator_unlock.