Aller au contenu principal
Version: v20 R4 BETA

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...) au même moment. 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
...
// 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 de l'objet Signal.
.signaled : Boolean    contient l'état 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
VersionModifications
v17 R4Ajout

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

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

|

Description

La commande New 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("This is my first signal")

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

If($signaled)
ALERT("myworker finished the work. Result: "+$signal.myresult)
Else
ALERT("myworker has not finished in less than 1s")
End if

La méthode doSomething est par exemple :

 #DECLARE ($signal : 4D.Signal)
//any processing
//...
Use($signal)
$signal.myresult:=$processingResult //retourner le résulat
$signal.trigger() // L'opération est terminée

.description

Historique
VersionModifications
v17 R4Ajout

.description : Text

Description

La propriété .description contient une description personnalisée de 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
VersionModifications
v17 R4Ajout

.signaled : Boolean

Description

La propriété .signaled contient l'état 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
VersionModifications
v17 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 qui attendent 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
VersionModifications
v17 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.