version 11 (Modifiée)
Semaphore (sémaphore{; nbTicks}) Booléen
Paramètre | Type | Description | |
sémaphore | Alpha | Sémaphore à tester et à positionner | |
nbTicks | Entier | Temps d'attente maximum | |
Résultat | Booléen | sémaphore a été correctement créé (Faux) ou | |
sémaphore était déjà créé (Vrai) |
Description
Un sémaphore est un drapeau visible par chaque poste client (l'ordinateur de chaque utilisateur) ou chaque process sur un même poste. Un sémaphore a simplement pour rôle d'exister ou de ne pas exister. Chaque méthode exécutée par un utilisateur peut tester la présence d'un sémaphore. En créant et en testant des sémaphores, vous permettez aux méthodes de communiquer entre les postes clients et les process.
La fonction Semaphore retourne Vrai si sémaphore existe. Si sémaphore n'existe pas, Semaphore le crée et retourne Faux. Un seul utilisateur à la fois peut créer un sémaphore. Si Semaphore retourne Faux, cela indique que sémaphore n'existait pas, mais cela signifie également que sémaphore a été créé et positionné dans le process d'où l'appel a été effectué.
Semaphore retourne Faux si le sémaphore n'existait pas. La fonction retourne également Faux si le sémaphore avait été déjà positionné par le process d'où l'appel a été effectué.
Un sémaphore est limité à 255 caractères, métacaractères ($, <>) inclus. Si vous passez une chaîne plus longue, elle est tronquée. Attention, 4D tient compte de la casse des caractères en ce qui concerne les noms de sémaphores (le programme considère par exemple que "MonSémaphore" est différent de "monsémaphore").
Le paramètre optionnel nbTicks vous permet de spécifier un délai d'attente en ticks (1 tick = 1/60ème de seconde) si sémaphore est déjà positionné. Dans ce cas, avant de retourner Vrai, la fonction attend, dans la limite du temps fixé, que sémaphore se libère (auquel cas elle retourne Faux). Si le délai expire sans que sémaphore ait été libéré, Semaphore retourne Vrai.
Il y a deux types de sémaphores dans 4D : les sémaphores locaux et les sémaphores globaux.
Un sémaphore local est visible par tous les process d'un même poste et seulement sur ce poste. Vous déclarez un sémaphore local en préfixant son nom avec le signe dollar ($). Les sémaphores locaux permettent de contrôler des opérations entre les différents process exécutés sur le même poste. Par exemple, un sémaphore local peut être utilisé pour gérer les accès à un tableau interprocess appelé par tous les process d'une base de données mono-utilisateur ou d'un poste client.
Un sémaphore global est visible par tous les utilisateurs et tous les process. Les sémaphores globaux permettent de contrôler des opérations entre les postes clients d'une base multi-utilisateurs.
Le principe de fonctionnement des sémaphores globaux et locaux est identique. Leur différence réside uniquement dans leur portée, c'est-à-dire leur visibilité. Dans 4D Server, les sémaphores globaux sont visibles pour tous les process de tous les postes clients. Un sémaphore local n'est visible que pour les process du poste client sur lequel il a été créé.
Avec 4D, les sémaphores globaux et locaux ont la même portée car il n'y a qu'un seul utilisateur. Cependant, si votre base est utilisée dans les deux environnements, n'hésitez pas à employer des sémaphores globaux et locaux, en fonction de vos besoins.
Les sémaphores ne servent pas à protéger l'accès aux enregistrements cette gestion est effectuée automatiquement par 4D et 4D Server. Les sémaphores ont pour but d'éviter que plusieurs utilisateurs effectuent la même opération en même temps.
Exemples
(1) Dans l'exemple suivant, vous souhaitez empêcher que deux utilisateurs effectuent simultanément une mise à jour globale des prix dans une table [Produits]. Pour cela, des sémaphores sont utilisés :
Si (Semaphore("MAJPrix")) ` Essai de création du sémaphore ALERTE("Un autre utilisateur est déjà en train de mettre à jour les prix. Essayez plus tard.") Sinon MAJdesPrix ` Méthode de mise à jour des prix EFFACER SEMAPHORE("MAJPrix")) ` Effacer le sémaphore Fin de si
(2) L'exemple suivant illustre l'utilisation d'un sémaphore local. Dans une base comportant plusieurs process, vous souhaitez maintenir une liste de "Choses à faire". Vous envisagez de la maintenir à jour dans un tableau interprocess et non dans une table. Vous devez empêcher les accès simultanés à l'aide d'un sémaphore. Dans ce cas, il vous suffit d'utiliser un sémaphore local car la liste "Choses à faire" est pour votre utilisation personnelle.
Le tableau interprocess est initialisé dans la méthode base Sur ouverture :
TABLEAU TEXTE (<>ListeAFaire;0) ` La liste de choses à faire est vide
Voici la méthode utilisée pour ajouter des éléments à la "liste des choses à faire" :
` Méthode projet AJOUTER LISTE A FAIRE ` AJOUTER LISTE A FAIRE (Texte) ` AJOUTER LISTE A FAIRE (Elément la liste à faire) C_TEXTE($1) ` Paramètre passé à la commande Si (Non (Semaphore("$AccèsListe";300))) ` Attendre 5 secondes si un sémaphore existe déjà $vlElem:=Taille tableau(<>ListeAFaire)+1 INSERER DANS TABLEAU(<>ListeAFaire;$vlElem) <>ListeAFaire{$vlElem}:=1 EFFACER SEMAPHORE("$AccèsListe") ` Effacer le sémaphore Fin de si
Vous pouvez appeler cette méthode depuis n'importe quel process.
Référence
EFFACER SEMAPHORE, Tester semaphore.