Bonjour
C'est pour la classe class_cache.inc.php de cache html de noren, et aussi pour mon site web.
Je cherche à faire une classe de gestion d'accès à une ressource en lecture/écriture, de telle manière que, si le fichier/ressource existe, on y accède en lecture, sinon le processus est censé écrire dedans, sans que d'autres processus ne puissent écrire en même temps.
J'hésite entre un lock bloquant et un lock non bloquant.
PHP ne permet pas théoriquement, les locks non bloquants, du moins de savoir si la ressource est disponible ou non, d'une manière suffisamment atomistique, avant le lock.
Mais, sur le PHP Manual, il y a cette classe ci-dessous ( transformée en classe par mes soins ).
Quelle est a meilleure solution, du point de vue rapidité ? Bloquant ou non bloquant ?
Pour le cache, la durée de la tâche est celle du chargement de la page.
Pour le reste, c'est un peu plus court
Merci beaucoup pour vos réponses.
Amicalement.
C'est pour la classe class_cache.inc.php de cache html de noren, et aussi pour mon site web.
Je cherche à faire une classe de gestion d'accès à une ressource en lecture/écriture, de telle manière que, si le fichier/ressource existe, on y accède en lecture, sinon le processus est censé écrire dedans, sans que d'autres processus ne puissent écrire en même temps.
J'hésite entre un lock bloquant et un lock non bloquant.
PHP ne permet pas théoriquement, les locks non bloquants, du moins de savoir si la ressource est disponible ou non, d'une manière suffisamment atomistique, avant le lock.
Mais, sur le PHP Manual, il y a cette classe ci-dessous ( transformée en classe par mes soins ).
Quelle est a meilleure solution, du point de vue rapidité ? Bloquant ou non bloquant ?
Pour le cache, la durée de la tâche est celle du chargement de la page.
Pour le reste, c'est un peu plus court
Merci beaucoup pour vos réponses.
Amicalement.
PHP:
<?php
class Semaphore_non_blocking {
const SHARED_MEMORY = 100;
public $fp_log = null;
private $projectId = null;
private $resourceSemaphore = null;
private $tokenSemaphore = null;
private $tokenValue = null;
private $resourceSemaphoreKey = null;
private $tokenSemaphoreKey = null;
private $tokenValueKey = null;
public function __construct($filename, $is_cache = false) {
if($is_cache === false) {
$this->projectId = "aplusbegalix";
} else {
$this->projectId = "abraracourcix";
}
$var = $filename . "_" . $this->projectId;
/**
$this->fp_log = fopen(basename($filename) . ".log", "w+");
if($this->fp_log === false) {
echo "failed to open : " . $filename . ".log" . "<br />\n";
return false;
}
**/
$this->resourceSemaphoreKey = (int)preg_replace("/[^0-9]/","",(preg_replace("/[^0-9]/","",md5($var))/35676248)/619876); // text to number system.
$this->tokenSemaphoreKey = $this->resourceSemaphoreKey + 1387655434;
$this->tokenValueKey = $this->resourceSemaphoreKey + 2386421167;
$tmp_array = array('$this->resourceSemaphoreKey' => $this->resourceSemaphoreKey,
'$this->tokenSemaphoreKey' => $this->tokenSemaphoreKey,
'$this->tokenValueKey' => $this->tokenValueKey);
// $this->myEcho(var_export($tmp_array, true));
if(($this->resourceSemaphoreKey == -1) ||
($this->tokenSemaphoreKey == -1) ||
($this->tokenValueKey == -1)) {
echo "failed to get key of semaphore. <nbr />\n";
return false;
}
$this->resourceSemaphore = sem_get($this->resourceSemaphoreKey, 1, 0666, true);
$this->tokenSemaphore = sem_get($this->tokenSemaphoreKey, 1, 0666, true);
$this->tokenValue = shm_attach($this->tokenValueKey, self::SHARED_MEMORY, 0666);
if(($this->resourceSemaphore === false) ||
($this->tokenSemaphore === false) ||
($this->tokenValue === false)) {
echo "failed to get semaphore. <nbr />\n";
return false;
}
$this->LOCK();
return $this;
}
public function __destruct() {
$this->UNLOCK();
// fclose($this->fp_log);
@shm_remove($this->tokenValue);
@shm_detach($this->tokenValue);
@sem_remove($this->tokenSemaphore);
@sem_remove($this->resourceSemaphore);
}
private function myEcho($v) {
// echo microtime() . ' ' . $v . "\n";
// fputs($this->fp_log, microtime() . ' ' . $v . "\n");
}
public function try_lock() {
// $this->myEcho('begin try_lock()');
// $this->myEcho('acquire token semaphore');
sem_acquire($this->tokenSemaphore);
// $this->myEcho(' token semaphore acquired');
$tmp = @shm_get_var($this->tokenValue, $this->tokenValueKey);
// $this->myEcho(' token value: ' . var_export($tmp, true));
$exit = $tmp;
if (!$exit) {
$tmp = @shm_put_var($this->tokenValue, $this->tokenValueKey, true);
$tmp = @shm_get_var($this->tokenValue, $this->tokenValueKey);
// $this->myEcho(' token new value: ' . var_export($tmp, true));
}
// $this->myEcho('release token semaphore');
sem_release($this->tokenSemaphore);
if ($exit) return false;
// $this->myEcho('acquire resource semaphore');
sem_acquire($this->resourceSemaphore);
// $this->myEcho(' resource semaphore acquired');
return true;
}
private function release() {
// $this->myEcho('release resource semaphore');
sem_release($this->resourceSemaphore);
// $this->myEcho('acquire token semaphore');
sem_acquire($this->tokenSemaphore);
// $this->myEcho(' token semaphore acquired');
$tmp = @shm_get_var($this->tokenValue, $this->tokenValueKey);
// $this->myEcho(' token value: ' . var_export($tmp, true));
$tmp = @shm_put_var($this->tokenValue, $this->tokenValueKey, false);
$tmp = @shm_get_var($this->tokenValue, $this->tokenValueKey);
// $this->myEcho(' token new value: ' . var_export($tmp, true));
// $this->myEcho('release token semaphore');
sem_release($this->tokenSemaphore);
}
private function LOCK() {
for ($triesLeft = 5; $triesLeft > 0 && !$this->try_lock(); $triesLeft--) {
// $this->myEcho('failed to acquire resource');
// $this->myEcho('wait for 1 sec');
usleep(1000);
// $this->myEcho('try again');
}
//paste here your code, accessing your resource
// $this->release();
}
private function UNLOCK() {
$this->release();
}
}
?>