Delcedo PHPLib
Manuel

lock

Protège l'exécution concurrentiel d'un code PHP critique

Description
void lock ( string $nom )
Liste de paramètres
nom

Le nom du verrou posé.

Le nom ne doit pas contenir de caractères invalides pour les noms de fichiers. Cette méthode fait appel à la fonction flock Nouvelle fenêtre.

Valeur de retour
void

Les processus (programmes) qui tournent sur un système d'exploitation, fonctionnent, aux yeux de l'utilisateur, en parallèle. Cette notion de parallélisme, pour un ordinateur ne peut exister (excepté pour les ordinateurs équipés de plusieurs processeurs). En effet, un processeur ne peut exécuté qu'un seul processus à la fois.

Pour réaliser le multi-tâche, et éviter de devoir attendre qu'un processus ne se termine avant de pouvoir en exécuter un autre, le système d'exploitation partage le temps d'utilisation de chaque processeur en tout petit laps de temps.

A chaque laps de temps, le système d'exploitation, suspend l'exécution du processus qui utilisait le processeur et réveille le processus suivant pour qu'il continue son exécution. A l'échelle de l'utilisateur, celui-ci a l'impression que les processus tournent en même temps.

Un problème se pose donc au niveau de la conception des programmes qui utilisent des ressources dites "critiques", car le système d'exploitation peut suspendre un processus à n'importe quelle ligne de code.

Si l'exemple suivant n'avait pas de verrous pour protéger la zone critique, l'exécution parallèle de ce script donnerait des valeurs différentes de celles attendues.

Exemple de pose des verrous
<?php

// Connexion
$db = new DataBase("localhost""site_du_chapeau""chapeau_melon""3t b0tt3 2 cu1r");

// Pose du verrou pour protéger la zone critique
$db->lock("admin_compteur");

/*** Début de la zone critique ***/

$resultat $db->exec("SELECT compteur FROM admin WHERE site = 'mon_super_site'");

$compteur $resultat[1]['compteur'];
$compteur $compteur 1;

// Simulation de la coupure du système d'exploitation en zone critique
sleep(10*rand());

// Mise à jour du compteur
$db->exec("UPDATE admin SET compteur = ".$compteur." WHERE site = 'mon_super_site'")

/*** Fin de la zone critique ***/

// Libération du verrou
$db->unlock("admin_compteur");

?>

Pour parer à ce problème, le développeur peut poser un verrou pour garantir l'exclusion des autres processus de cette ressource critique. Deux verrous ne peuvent pas être posés en même temps, en effet, la pose d'un verrou fait appel à des instructions spéciales gérées par le système d'exploitation.
Le premier à avoir poser le verrou pourra exécuter le code qui suit, tandis que le deuxième attendra que le verrou soit libéré, et ainsi de suite pour tous les autres processus qui demanderait l'accès à la ressource.

Attention à votre conception ! Un code mal écrit peut amener à des situations d'interblocages, et la seule solution pour débloquer les processus bloqués sont d'en tuer au moins un. Si vous exécutez les deux scripts d'interblocage, un des deux scripts se terminera avec l'erreur de dépassement du temps maximal d'exécution, alors que le deuxième terminera correctement son exécution grâce à la mort du premier processus.

Exemple d'interblocage - page_1.php
<?php

// Pose d'un premier verrou
$db->lock("admin_compteur");

// Simulation de la coupure du système d'exploitation en zone critique
sleep(10);
echo 
"Script 1 Réveillé";

// Attente libération du verrou posé par script_2.php
$db->lock("admin_visites");

echo 
"Script 1 en zone critique";

$db->unlock("admin_visites");
$db->unlock("admin_compteur");

?>
Exemple d'interblocage - page_2.php
<?php

$db
->lock("admin_visites");

// Simulation de la coupure du système d'exploitation en zone critique
sleep(10);
echo 
"Script 2 réveillé";

// Attente libération du verrou posé par script_1.php
$db->lock("admin_compteur");

echo 
"Script 2 en zone critique";

$db->unlock("admin_compteur");
$db->unlock("admin_visites");


?>
Delcedo.com | Creative Commons License