Sémaphore en php ? Comment regler ma Fatal Error ?

Nouveau WRInaute
J'ai tenté de faire un petit code pour banir les aspirateurs de site via le htaccess (j'aimerai si possible utiliser le moins possible ma bdd)

Donc, pour gerer les acces simmultané en écriture au fichier, j'aimerai ajouté des sémaphores.
J'ai essayé ca :

<?
$nowait = 0; /* initialisation */
$id = sem_get(0xF00);
sem_acquire($id); /* on bloque */
$htaccess="\nDeny from ".$_SERVER["REMOTE_ADDR"];
$fp = fopen(".htaccess","a");
fputs($fp,$htaccess);
fclose($fp);
sem_release($id); /* on relache */
?>

Mais visiblement ca ne marche pas, j'ai un :
Fatal error: Call to undefined function: sem_get()

Quelqu'un a une idée de la maniere dont je peut résoudre ce probleme ?
 
Nouveau WRInaute
Arf, j'ai compris, pour activer le support des sémaphores il faut compiler PHP avec l'option --enable-sysvsem.
Mouais bon ... y a pas un autre moyen de faire ?
 
WRInaute accro
Bonsoir

en PHP, la fonction flock($fp, $param), permet de faire un verrou de différents types, suivant la valeur de $param.

Celà peut être un verrou en écritue ou en lecture, bloquant ou non bloquant, etc... sur le fichier dont le handle donné par fopen($filename, $rights), est: $fp

Avec ça, tu peux, en associant un fichier réel d'enclenchement de la tâche ( s'il n'existe pas ) dont tu testes l'existence après avoir posé le verrou en mode bloquant sur un autre fichier verrou, dont le nom sera caractérisitique de la tâche à effectuer...

Au global, donc, tu as:

- $filename Un fichier dont tu connais le nom, d'après la tâche à effectuer ou ne pas effectuer,
- $verrou Un fichier de verrouillage, dont le nom est déduit automatiquement de la tâche à effectuer ou ne pas effectuer.

Voici l'algorithme:

// Tache à effectuer ou non ?
if(!file_exists($filename))
{ // Fichier n'existe pas, pose du verrou mode bloquant.
if(!($fp_verrou = @fopen($verrou, "a"))
{ // Verrou apparemment posé.
// Il faut attendre que le fichier $verrou
// n'existe plus.
while(file_exists($verrou))
{ sleep(2);
}
}
else
{ // Pose du verrou.
$param_bloquant = // Mode bloquant en écriture, voir PHP Manual...
if(!@flock($fp_verrou, $param_bloquant))
{ // Verrou apparemment déjà posé,
// Il faut attendre que le fichier verrou
// n'existe plus.
while(files_exists($verrou))
{ sleep(2);
}
}
else
{ // Le verrou est posé correctement,
// exécution de la tâche.
//
// Traitement de la tâche...
// Au cours de cette tâche, le fichier
// $filename est créé et alimenté
// Eventuellement d'autres traitements
// peuvent être faits.
//
// Fin de tâche, déverrouillage
// du fichier verrou,
// puis effacement du fichier verrou
$param_debloquant = // ... Mode débloquant, Voir PHP Manual...
@flock($fp_verrou, $param_debloquant);
@flclose($fp_verrou);
// Effacement du fichier verrou.
@unlink($verrou);
}
}
}
else
{ // La tâche a déjà été effectuée entièrement,
// Traitement complémentaire éventuel.
}
// ... Suite du script,
// ou saut vers un autre script.


J'ai mis au point un algorithme quasi équivalent à celui-là sur mon propre site, pour éviter les accès concurrentiels en écriture, lors de la mise à jour de la liste des Courses en début d'après-midi, ou lors de l'écriture de mes fichiers temporaires des résultats passés des Courses, pour chaque Courses consultées...

L'algorithme ci-dessus, ne fonctionne que si la tâche à effecuer, est suffisament courte.

Dans le cas contraire, il faut tester l'existence simultanée de $filename et $verrou, ou l'un ou l'autre, et faire les traitements ad hoc, tout en débloquant systématiquement $verrou après avoir créé $filename lors de l'entrée dans la tâche...

Bien à toi.

Jean-François
 
Discussions similaires
Haut