2016-04-14 15 views
3

PHP'de bir mutex yöntemine ihtiyacım var, bu sayede münhasırlık değerini değişken bir değerde tutar. Bu, aynı değere sahip iş parçacıklarının bu yöntemi bir kerede girmesi gerekirken, farklı değerlere sahip iş parçacıkları isteğe bağlı olarak bu yönteme erişebilir. bu yöntem Verilen örnek içinDeğişken değeri başına PHP'de bir muteks yöntemi nasıl oluşturulur

:

/** 
* @param integer $value 
*/ 
function mutexMethod($value) 
{ 
    // Lock for value $value 
    echo 'processing'; 
    sleep(2); 
    echo 'this is so heavy'; 
    // Unlock for value $value 
} 

Örneğin (Bu mi apache üzerinden çalıştırılacak): bir birinci çözüm olarak

time | 
0 | php > mutexMethod(1); | php > mutexMethod(2); | php > mutexMethod(1); 
1 | processing   | processing   | 
2 |      |      | 
3 | this is so heavy  | this is so heavy  | processing 
4 |      |      | 
5 |      |      | this is so heavy 

, I semaphores kullanılarak denedik ancak $value, herhangi bir değer alabilir, çok hızlı bir şekilde semaphores alanından çıkıyorum (bunları kullandıktan sonra semaforları çıkarmayı denedim ama bu, onu bekleyen diğer konuları kırıyor ve onları bekleyen herhangi bir konu olup olmadığını bilmiyorum, Onların keyfini kaldıramıyorum ily.

İkinci bir çözüm olarak, $value numaralı ada sahip bir dosya oluşturmayı ve flock'u kullanarak başka bir iş parçacığını kilitlemeyi denedim. Bu CLI çalıştı rağmen, apache ile çalışmayı başaramadı. Kesinlikle dosyayı kilitlemişti, ancak bu kilidi asla serbest bırakmadı, böylece ilk talep zaman aşımına uğradı (30 saniye sonra).

Son olarak, MySQL kilitlerini kullanmakla birlikte, MySQL örneğini bu tür şeyler için kullanmak istemediğimiz kadar önlemek istiyorum. İdeal olarak saf bir PHP çözümü istiyoruz.

Bu sorunu nasıl çözebilirim konusunda bir fikriniz var mı? Tek-semafor çözümlerinden kaçınmak istiyorum (kilitleri takip edebilecek bir dosyaya erişimi kontrol etmek için tek bir semaforun olması gibi). Bu, büyük bir darboğaz yaratacaktır (özellikle farklı değerlere sahip olan iplikler için).

Çok teşekkür ederim.

+0

Çözdüğünüz daha geniş bir sorun üzerinde durulabilecek misiniz? Görebildiğim kadarıyla, olası bir çözüm, değerleri bir kümede saklamak ve bir iş parçacığının set üyeliğini değiştirmek için bir mutex edinmesi gereken erişim işlevleri oluşturmak olabilir. Bu şekilde, iş parçacıklarının "check-out" ve "check-in" değerlerini "senkronize" etmesi için senkronize bir yol elde edersiniz. – aednichols

+0

Web üzerinde bir yarış durumunu çözmeye çalışıyorum, böylece kullanıcılar bir kimliği olan bir nesne için bazı hesaplamaları (nispeten pahalı ve zaman alıcı) gerçekleştirmek için bir algoritmayı tetikliyorlar. Öyleyse fikir, bu kimliğe dayanarak, "sıra" ya da sadece istekleri bloke etmek ve bunları tek tek işlemektir. Aynı kimlik için isteğin aynı anda yapılmasına izin verirsem, önceki hesaplamayı kaybedebilirim. Ancak buradaki nokta, farklı kimlikler için taleplerin herhangi bir dezavantaj olmaksızın aynı anda gerçekleştirilebilmesidir. – carlosV2

+0

Belirli bir kimlik için hesaplamanın sonucu her seferinde aynı mıdır? [Memoization] düşünmelisiniz gibi geliyor (https://en.wikipedia.org/wiki/Memoization) – aednichols

cevap

0

https://github.com/arvenil/ninja-mutex

sürüsü/MySQL/Redis/Memcache'ı adaptör

Bunların hepsini denemeniz ve çalışır bir seçim olabilir bu

<?php 
require 'vendor/autoload.php'; 

use NinjaMutex\Lock\MemcacheLock; 
use NinjaMutex\MutexFabric; 

$memcache = new Memcache(); 
$memcache->connect('127.0.0.1', 11211); 
$lock = new MemcacheLock($memcache); 
$mutexFabric = new MutexFabric('memcache', $lock); 
if ($mutexFabric->get($value)->acquireLock(1000)) { 
    // Do some very critical stuff 

    // and release lock after you finish 
    $mutexFabric->get($value)->releaseLock(); 
} else { 
    throw new Exception('Unable to gain lock for very critical stuff!'); 
} 
gibi görünebilir davanız örnekte

İlgili konular