2008-10-08 9 views
6

Java, C ve C++ 'ya aşina olduğumdan, herhangi bir zamanda bir kaynağa yalnızca bir iş parçacığının erişebildiğini kontrol etme yolları vardır. Şimdi benzer bir şey aramaktayım ama PHP 5.x. PHP 5.x eşzamanlı dosya erişimi (veritabanı yok)

bir örnekle sorunumu formüle etmek için:

Ben sadece bir sayı, bir sayfa yükleme sayacı değerini saklayan bir ASCII dosyası var. Uygulama dağıtımında dosya basitçe 0 tutacaktır. Her erişim için değer bir artırılacaktır. Amaç sayfa yüklerini takip etmektir.

Sorun, birçok kullanıcının eşzamanlı olarak sayacı içeren sayfaya eriştiğinde ortaya çıkar. A iş parçacığı mevcut değeri okuduğunda, 11 diyelim, B olarak adlandırdığımız başka bir iş parçacığı, değeri okuyor, yine de 11 sonra. İlk iş parçacığı A okuma değerini artırır ve dosyada 12 yazar ve kapatır. Daha sonra ikinci iplik B, okunan değeri artırır, bu 11, 12 olur ve dosyaya yazar. 12 değeri, gerçekten 13 olması gerektiğinde dosyada saklanır.

Başka bir programlama dilinde bunu bir muteks kullanarak çözmüş olurdum. Anladığım kadarıyla modüllerin bir parçası olarak muteksler, paylaşılmış hafıza ve diğer işlevler var. Ama orada "çoğu sunucuda" çalışan bir çözüm istiyorum. Platform bağımsız. En ucuz web sunucularında yüklü. Bu problem için iyi bir çözüm var mı? Ve yoksa, veritabanını kullanmanın bir yolu seçeneği değilse hangi yolu kullanırsınız?

cevap

7

Sen sürünün php'nin varyantını deneyebilirsiniz (http://www.php.net/flock)

Ben benzer bir şey olmasını sağlayacak

(bu varsayar zaten var ve dosyadaki bir sayaç /tmp/counter.txt dosyası):

<?php 

$fp = fopen("/tmp/counter.txt", "r+"); 

echo "Attempt to lock\n"; 
if (flock($fp, LOCK_EX)) { 
    echo "Locked\n"; 
    // Read current value of the counter and increment 
    $cntr = fread($fp, 80); 
    $cntr = intval($cntr) + 1; 

    // Pause to prove that race condition doesn't exist 
    sleep(5); 

    // Write new value to the file 
    ftruncate($fp, 0); 
    fseek($fp, 0, SEEK_SET); 
    fwrite($fp, $cntr); 
    flock($fp, LOCK_UN); // release the lock 
    fclose($fp); 
} 

?> 
+0

Örnek problemin bir çözümü ile bilgilendirici cevap, teşekkür ederim! Fclose ($ fp) kilidi de serbest bıraksa bile, arama çağrısının ($ fp, LOCK_UN) güzel olduğunu düşünüyorum. Yine de bir sorum var, neden fwrite ($ fp, $ cntr. "\ N") satırında yeni satırlardan boşluk ekliyorsunuz? –

+0

Oops, bu benim özgün gelişimimin bir parçasıydı. Sadece fseekkat kullanmadan fseek kullanacaktım. Boşlukları eklemek, satırdaki diğer karakterleri silmeyi garanti eder (azaltma için daha önemlidir.) Artık gerekli olmadığından, yukarıda düzenlenmiş. – terson

3

PHP'nin flock() işlevi giden yoldur. Bununla birlikte, dosyaya tüm eriştiğinden emin olmak için önce bir sürü arama() tarafından korunduğundan emin olmalısınız. Açık bir şekilde bunu yapmazsanız, PHP dosyanın kilitli olup olmadığını kontrol etmez. Kavram, mutekslerle (paylaşılan kaynakları koruyarak) neredeyse aynıdır, fakat özel vurgu yapmak için yeterince önemlidir.

İlgili konular