Aller au contenu principal
Version: 20 R6

Signal

Les signaux sont des outils fournis par le langage 4D pour gérer les interactions et éviter les conflits entre les process dans une application multiprocessus. Les signaux vous permettent de vous assurer qu'un ou plusieurs process attendront la fin d'une tâche spécifique avant de poursuivre leur exécution. Tout process peut attendre et/ou libérer un signal.

Les sémaphores peuvent également être utilisés pour gérer les interactions. Les sémaphores permettent de s'assurer que deux ou plusieurs process ne modifient pas la même ressource (fichier, enregistrement...) en même temps. Seul le process qui a posé le sémaphore peut le retirer.

Objet signal

Un signal est un objet partagé qui doit être passé comme paramètre aux commandes qui appellent ou créent des workers ou des process.

Un objet 4D.Signal contient les méthodes et propriétés intégrées suivantes :

Tout worker/process appelant la méthode .wait() suspend son exécution jusqu'à ce que la propriété .signaled soit mise à true. Lorsque vous êtes en attente d'un signal, le process appelant n'utilise pas de CPU. Cela peut être très intéressant pour les performances des applications multiprocess. La propriété .signaled devient est mise à True lorsqu'un worker/processus appelle la méthode .trigger().

A noter que pour éviter les situations de blocage, la méthode .wait() peut également revenir après qu'un délai d'attente défini ait été atteint.

Les objets signal sont créés à l'aide de la commande New signal.

Travailler avec des signaux

Dans 4D, vous créez un nouvel objet signal en appelant la commande New signal. Une fois créé, ce signal doit être passé en paramètre aux commandes New process ou CALL WORKER afin qu'elles puissent le modifier lorsqu'elles ont terminé la tâche que vous souhaitez attendre.

  • signal.wait() doit être appelé par le worker/process qui a besoin qu'un autre worker/process termine une tâche pour pouvoir continuer.
  • signal.trigger() doit être appelé par le worker/process qui a terminé son exécution afin de libérer tous les autres.

Une fois qu'un signal a été libéré par un appel à signal.trigger(), il ne peut plus être réutilisé. Si vous souhaitez définir un autre signal, vous devez à nouveau appeler la commande New signal.

Etant donné qu'un objet signal est un objet partagé, vous pouvez l'utiliser pour retourner les résultats des workers/process appelés, à condition de ne pas oublier d'écrire les valeurs dans une structure Use...End use (voir exemple

Exemple

 var $signal : 4D.Signal

// Création d'un signal
$signal:=New signal

// appel du process principal et exécution de la méthode OpenForm
CALL WORKER(1;"OpenForm";$signal)
// autre calcul
...
// En attente de la fin du process
$signaled:=$signal.wait()

// Traitement des résultats
$calc:=$signal.result+...

Méthode OpenForm :

 #DECLARE ($signal : 4D.Signal)  
var $form : Object
$form:=New object("value";0)

// Ouvrir le form
$win:=Open form window("Information";Movable form dialog box)
DIALOG("Information";$form)
CLOSE WINDOW($win)

// Ajout d'un nouvel attribut à votre objet partagé $signal pour passer votre résultat à l'autre process :
Use($signal)
$signal.result:=$form.value
End use

// Envoyer le signal au process en attente
$signal.trigger()

Sommaire

.description : Text
contient une description personnalisée pour l'objet Signal
.signaled : Boolean
contient le statut courant de l'objet Signal
.trigger( )
met la propriété signaled de l'objet signal à true
.wait( { timeout : Real } ) : Boolean
place le process courant en attente jusqu'à ce que la propriété .signaled de l'objet signal devienne true ou que le timeout optionnel expire

New signal

Historique
ReleaseModifications
17 R4Ajout

New signal { ( description : Text ) } : 4D.Signal

ParamètresTypeDescription
DescriptionText->Description du signal
Résultat4D.Signal<-Object encapsulant le signal

Description

La commande New signal crée un objet 4D.Signal.

Un signal est un objet partagé qui peut être passé en paramètre depuis un worker ou un process à un autre worker ou process, de manière à ce que :

  • le worker/process appelé puisse mettre à jour l'objet signal après qu'un traitement spécifique soit terminé
  • le worker/process appelant puisse stopper son exécution et attende jusqu'à ce que le signal soit mis à jour, sans consommer aucune ressource CPU.

Optionnellement, dans le paramètre description, vous pouvez passer un texte personnalisé décrivant le signal. Ce texte peut également être défini après la création du signal.

Comme l'objet signal est un objet partagé, il peut aussi être utilisé pour maintenir des propriétés utilisateur, y compris la propriété .description, via l'appel de la structure Use...End use.

Valeur retournée

Un nouvel objet 4D.Signal.

Exemple

Voici un exemple type de worker qui définit un signal :

 var $signal : 4D.Signal
$signal:=New signal("Ceci est mon premier signal")

CALL WORKER("myworker";"doSomething";$signal)
$signaled:=$signal.wait(1) //patienter 1 seconde au maximum

If($signaled)
ALERT("myworker a terminé le travail. Résultat : "+$signal.myresult)
Else
ALERT("myworker n'a pas terminé en moins d'1 seconde")
End if

La méthode doSomething est par exemple :

 #DECLARE ($signal : 4D.Signal)
//tout traitement
//...
Use($signal)
$signal.myresult:=$processingResult //renvoi du résultat
End use
$signal.trigger() // Le travail est terminé

.description

Historique
ReleaseModifications
17 R4Ajout

.description : Text

Description

La propriété .description contient une description personnalisée pour l'objet Signal.

.description peut être définie à la création de l'objet signal ou à tout moment. Notez que comme l'objet Signal est un objet partagé, tout accès en mode écriture à la propriété .description doit être encadré par les mots-clés Use...End use.

Cette propriété est en lecture-écriture.

.signaled

Historique
ReleaseModifications
17 R4Ajout

.signaled : Boolean

Description

La propriété .signaled contient le statut courant de l'objet Signal. Lorsque le signal est créé, .signaled est False. Elle devient True lorsque la fonction .trigger( ) est appelée sur l'objet.

Cette propriété est en lecture seule.

.trigger()

Historique
ReleaseModifications
17 R4Ajout

.trigger( )

ParamètresTypeDescription
Ne requiert aucun paramètre

Description

La fonction .trigger() met la propriété signaled de l'objet signal à true et réveille tous les workers ou process attendant ce signal.

Si le signal est déjà dans l'état signaled (i.e., la propriété signaled est déjà true), la fonction ne fait rien.

.wait()

Historique
ReleaseModifications
17 R4Ajout

.wait( { timeout : Real } ) : Boolean

ParamètresTypeDescription
timeoutReal->Délai d'attente maximum du signal en secondes
RésultatBoolean<-Etat de la propriété .signaled

Description

La fonction .wait() place le process courant en attente jusqu'à ce que la propriété .signaled de l'objet signal devienne true ou que le timeout optionnel expire.

Pour prévenir tout code bloquant, vous pouvez passez un temps d'attente maximum en secondes dans le paramètre timeout (les décimales sont acceptées).

Attention : L'appel de .wait( ) sans timeout dans le process principal de 4D n'est pas recommandé car il pourrait geler l'ensemble de l'application 4D.

|

La fonction retourne la valeur de la propriété .signaled. Evaluer cette valeur permet de savoir si la fonction a retourné à cause de l'appel de .trigger( ) (.signaled est true) ou si le timeout a expiré (.signaled est false).

L'état d'un process qui attend un signal est En attente d'un marqueur interne.