Domanda

Conosco principalmente Java, C e C ++ in cui esistono modi per controllare che un solo thread acceda a una risorsa in un dato momento. Ora sono alla ricerca di qualcosa di simile ma in PHP 5.x.

Per formulare il mio problema con un esempio:

Ho un file ASCII che memorizza solo un numero, il valore di un contatore del caricamento della pagina. Al momento della distribuzione dell'applicazione il file conterrà semplicemente 0. Per ogni accesso il valore verrà incrementato di uno. L'obiettivo è tenere traccia dei carichi delle pagine.

Il problema si presenta quando molti utenti accedono contemporaneamente alla pagina che contiene il contatore. Quando il thread A ha letto il valore corrente, diciamo che è 11, un altro thread che chiamiamo B legge il valore, sempre 11. Quindi il primo thread A incrementa il valore letto e scrive 12 nel file e lo chiude. Quindi il secondo thread B, incrementa il valore letto, che era 11, ne ottiene 12 e lo scrive nel file. Il valore 12 è memorizzato nel file, quando in realtà avrebbe dovuto essere 13.

In un altro linguaggio di programmazione avrei risolto questo problema usando un mutex. Capisco che ci sono mutex, memoria condivisa e altre funzionalità come parte dei moduli. Ma vorrei una soluzione che funzioni su "la maggior parte dei server" là fuori. Piattaforma indipendente. Installato sulla maggior parte degli host web economici. C'è una buona soluzione a questo problema? E se non lo è, in che modo prenderesti se l'uso di un database non è un'opzione ?

È stato utile?

Soluzione

Potresti provare la variante di flop di php ( http://www.php.net/flock )

Immagino qualcosa di simile a (questo presuppone che il file /tmp/counter.txt esiste già e abbia un contatore nel file):

<?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);
}

?>

Altri suggerimenti

La funzione flock () di PHP è la strada da percorrere. Tuttavia, devi prima assicurarti che tutti gli accessi al file siano protetti da una chiamata a flock (). PHP non controllerà se il file è bloccato a meno che tu non effettui esplicitamente la chiamata per farlo.

Il concetto è praticamente identico a quello dei mutex (protezione delle risorse condivise, ecc.), ma è abbastanza importante da dare particolare enfasi.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top