IPC System V : Sémaphore
 


   Les sémaphores système V sont une généralisation des sémaphores de Dijkstra pour la gestion des accès concurrents à une ressource. Ces primitives permettent de réaliser de manière atomique un ensemble d'opérations sur un ensemble de sémaphores. Cette extension permet d'éviter les verrous mortels : tous les sémaphores désignés sont modifiés ou aucun.

   Chaque ensemble de sémaphores est repéré par une clef qui représente un tableau de sémaphores. Un sémaphore, en système V, est constitué de :

  * La valeur du sémaphore.
  * Le numéro du dernier processus l'ayant manipulé.
  * Le nombre de processus en attente d'une augmentation.
  * Le nombre de processus en attente d'une mise à zéro.

Les opérations sont définies par une valeur entière interprétée comme suit:

  * Supérieure à zéro : La valeur du sémaphore est augmentée de la valeur correspondante. Tous les processus en attente d'une augmentation du sémaphores sont réveillés.

  * Egale à zéro : Teste si le sémaphore a la valeur 0. Si ce n'est pas le cas,  le processus est mis en attente de la mise à zéro du sémaphore.

  * Inférieur à zéro : La valeur (absolue) est retranchée du sémaphore. Si le résultat est nul, tous les processus en attente de cet événement sont réveillés. Si le résultat est négatif, le processus est mis en attente d'une augmentation du sémaphore.

Note : Lorsqu'un processus est mis en attente d'un événement, tous les sémaphores qui ont été modifiés par semop sont restaurés afin de garantir l'atomicité.

Dans l'exemple suivant on va utiliser le module IPC:SysV de CPAN, on aurait pu utiliser les commande C.

Ce module est un module objet donc nous allons utiliser les méthodes applicables à un objet Semaphore.

Exemple:

Executer le programme suivant dans un shell

use IPC::SysV qw( S_IRWXU IPC_CREAT);
use IPC::Semaphore;

$sem=new        IPC::Semaphore(245,1,S_IRWXU|IPC_CREAT);
$sem->setall( 1);#initialiser le tableau de sem
#prendre la semaphore
#attendre qu'il passe a 0

$sem->op(0,0,IPC_NOWAIT);

Le programme précédent est bloqué, éxecuter le code suivant dans un autre shell

use IPC::SysV qw(IPC_PRIVATE S_IRWXU IPC_CREAT);
use IPC::Semaphore;

$sem=new        IPC::Semaphore(245,1,S_IRWXU|IPC_CREAT);
$sem->op(0,-1,IPC_NOWAIT);
$sem->remove;

#Le processus précédent s’arrête