Aller au contenu principal
Version : 21 R4 BETA

Processes et Workers

Le multitâche dans 4D est la capacité d'exécuter plusieurs opérations simultanément. Ces opérations sont appelées process. Les process multiples sont comme plusieurs utilisateurs sur le même ordinateur, chacun travaillant à sa propre tâche. Cela signifie essentiellement que chaque méthode peut être exécutée en tant que tâche distincte de la base de données.

Si vous écrivez du code thread-safe, vous pouvez créer des process préemptifs qui pourront tirer parti des ordinateurs multi-cœurs dans vos applications compilées, pour une exécution plus rapide.

note

L'application 4D crée des process pour ses propres besoins, par exemple le process Main pour gérer l'affichage des fenêtres de l'interface utilisateur, le process Design pour gérer les fenêtres et les éditeurs de l'environnement de Développement (notez que tous deux sont des process workers), le process Web Server, le process Cache Manager, le process Indexing ou le process On Event Manager.

Créer et supprimer des process

Il existe plusieurs façons de créer un nouveau process :

  • Exécuter une méthode en mode Développement en sélectionnant la case à cocher Nouveau process dans la boîte de dialogue d'exécution de méthode. La méthode choisie dans ce dialogue est la méthode process.
  • Utiliser la commande New process. La méthode passée en paramètre à la commande New process est la méthode process.
  • Utiliser la commande Execute on server afin de créer une procédure stockée sur le serveur. La méthode passée en paramètre à la commande est la méthode process.
  • Utiliser la commande CALL WORKER. Si le process du worker n'existe pas déjà, il est créé.
note

Dans les applications Desktop, des process peuvent être exécutés lors de la sélection de commandes de menu. Dans l'Éditeur de barre de menus, sélectionnez la commande de menu et cliquez sur la case à cocher Démarrer un nouveau process. La méthode associée à la commande de menu est la méthode de process.

Un process peut être effacé dans les conditions suivantes (les deux premières sont automatiques) :

  • Lorsque l'exécution de la méthode du process est terminée
  • Lorsque l'utilisateur quitte l'application
  • Si vous arrêtez le process de manière procédurale ou si vous utilisez le bouton Abort dans le débogueur ou dans l'Explorateur d'exécution
  • Si vous appelez la commande KILL WORKER (pour supprimer un process worker uniquement).

Un process peut créer un autre process. Les process ne sont pas organisés de manière hiérarchique - tous les process sont égaux, quel que soit le process à partir duquel ils ont été créés. Une fois que le process "parent" a créé un process "enfant", le process enfant se poursuit, que le process parent soit toujours en cours d'exécution ou non.

Éléments d'un process

Chaque process contient des éléments spécifiques qu'il peut traiter indépendamment des autres process.

Éléments de langage

  • Variables : Chaque process possède ses propres [variables process] (../Concepts/variables#variables-process). Les variables process ne sont reconnues que dans le cadre de leur process natif.
  • Ensembles process : Chaque process a ses propres ensembles process. LockedSet est un ensemble process. Les ensembles process sont effacés dès que la méthode process est terminée.
  • Méthode de gestion des erreurs : Chaque process peut avoir sa propre méthode de gestion des erreurs.
  • Fenêtre du débogueur : Chaque process peut avoir sa propre fenêtre de débogage.

Éléments d'interface

Les éléments d'interface sont utilisés dans les Applications Desktop. Il s'agit des éléments suivants :

  • Barre de menus : Chaque process peut avoir sa propre barre de menus courante. La barre de menus du process au premier plan est la barre de menus courante de l'application.
  • Une ou plusieurs fenêtres : Chaque processus peut avoir plusieurs fenêtres ouvertes simultanément. A l'inverse, des process peuvent n'avoir pas de fenêtre du tout.
  • Une fenêtre active (de premier plan) : Bien qu'un process puisse disposer de plusieurs fenêtres ouvertes simultanément, chaque process n'a qu'une fenêtre active. Pour avoir plusieurs fenêtres actives à la fois, vous devez démarrer plusieurs process.
  • Formulaires d'entrée et de sortie : Les formulaires d'entrée et de sortie par défaut peuvent être définis de manière procédurale pour chaque table dans chaque process.
info
  • Par défaut, les process ne comportent pas de barre de menus, ce qui signifie que les raccourcis standard du menu Edition (notamment couper / copier / coller) ne sont pas disponibles dans les fenêtres des process. Lorsque vous appelez les dialogues ou les éditeurs de 4D (éditeur de formules, éditeur de recherches...) depuis un process, assurez-vous que l'équivalent d'un menu Edition est installé dans le process si vous souhaitez que l'utilisateur bénéficie des raccourcis clavier de type copier/coller.
  • Les process exécutés sur le serveur (procédures stockées) et les process préemptifs ne doivent pas contenir d'éléments d'interface.
note

Chaque process a également une sélection courante et un enregistrement courant par table. Pour plus d'informations sur ces concepts, veuillez vous référer à doc.4d.com.

Process sur clients

Lorsque vous créez un process sur un 4D distant, un process "jumeau" est créé sur le serveur pour gérer l'accès aux données et le contexte de la base de données dès que nécessaire, c'est-à-dire la première fois que le process sur le 4D distant doit accéder aux données.

Pour des raisons d'optimisation, si aucun accès au serveur n'est nécessaire, par exemple si le process sur le 4D distant exécute une méthode de gestion d'événements ou contrôle des fenêtres flottantes, aucun process jumeau n'est créé sur le serveur.

Process Workers

L'utilisation d'un process Worker est un moyen simple et puissant d'échanger des informations entre les process. Cette fonctionnalité est basée sur un système de messagerie asynchrone qui permet d'appeler des process et des formulaires et de leur demander d'exécuter des méthodes avec des paramètres dans leur propre contexte.

Un process worker peut être "engagé" par n'importe quel process (en utilisant la commande CALL WORKER) pour exécuter des méthodes projet avec des paramètres dans leur propre contexte, permettant ainsi l'accès à des informations partagées.

info

Dans les applications Desktop, une méthode projet peut également être exécutée avec des paramètres dans le contexte de n'importe quel formulaire en utilisant la commande CALL FORM.

Cette fonctionnalité répond aux besoins suivants en matière de communication interprocess de 4D :

  • Étant donné qu'ils sont pris en charge par les process coopératifs et préemptifs, ils constituent la solution idéale pour la communication interprocess dans les process préemptifs (les variables interprocess sont dépréciées et ne sont pas autorisées dans les process préemptifs).
  • Ils constituent une alternative simple aux sémaphores, qui peuvent être lourds à mettre en place et complexes à utiliser
note

Bien qu'ils aient été conçus principalement pour la communication interprocess dans le contexte de process préemptifs, CALL WORKER et CALL FORM peuvent être utilisés avec des process coopératifs.

Utilisation des workers

Un worker est utilisé pour demander à un process d'exécuter des méthodes projet. Un worker est composé de :

  • un nom unique (attention : le nom est sensible à la casse), également utilisé pour nommer le process qui lui est associé
  • un process associé, qui peut exister ou non à un moment donné
  • une boîte aux lettres
  • une méthode de démarrage (facultatif)

Vous demandez à un worker d'exécuter une méthode projet en appelant la commande CALL WORKER. Le worker et sa boîte aux lettres sont créés lors de la première utilisation ; le process qui lui est associé est également lancé automatiquement lors de la première utilisation. Si le process worker meurt par la suite, la boîte aux lettres reste ouverte et tout nouveau message dans la boîte lancera un nouveau process worker.

L'animation suivante illustre cette séquence :

Contrairement à un process créé avec la commande New process, un process worker reste en vie après la fin de l'exécution de la méthode process. Cela signifie que toutes les exécutions de méthodes pour le même worker seront exécutées dans le même process, qui conserve toutes les informations relatives à l'état du process (variables process, enregistrement courant et sélection courante, etc.). Par conséquent, les méthodes exécutées successivement accèdent aux mêmes informations et les partagent, ce qui permet la communication entre les process. La boîte aux lettres du worker traite les appels successifs de manière asynchrone.

CALL WORKER encapsule à la fois le nom de la méthode et les arguments de la commande dans un message qui est posté dans la boîte aux lettres du worker. Le process worker est alors lancé, s'il n'existe pas déjà, et il lui est demandé d'exécuter le message. Le process worker est alors lancé, s'il n'existe pas déjà, et il lui est demandé d'exécuter le message. Cela signifie que CALL WORKER sera généralement renvoyé avant que la méthode ne soit réellement exécutée (le traitement est asynchrone). C'est pourquoi CALL WORKER ne renvoie aucune valeur. Bien entendu, dans ce cas, l'appelant lui-même doit être un worker.

Il n'est pas possible d'utiliser CALL WORKER pour exécuter une méthode dans un process créé par la commande New process. Il n'est pas possible d'utiliser CALL WORKER pour exécuter une méthode dans un process créé par la commande New process. Seuls les process worker ont une boîte aux lettres et peuvent donc être appelés par CALL WORKER.

Les process worker peuvent être créés sur 4D Server par l'intermédiaire de procédures stockées : par exemple, vous pouvez utiliser la commande Execute on server pour exécuter une méthode qui appelle la commande CALL WORKER.

Un process worker est fermé par un appel à la commande KILL WORKER, qui vide la boîte aux lettres du worker et demande au process associé d'arrêter de traiter les messages et de terminer son exécution dès que la tâche en cours est terminée.

La méthode de démarrage d'un worker est la méthode utilisée pour créer le worker (à la première utilisation). La méthode de démarrage d'un worker est la méthode utilisée pour créer le worker (à la première utilisation).

Le process principal créé par 4D lors de l'ouverture d'une base de données pour les modes utilisateur et application est un process worker et peut être appelé en utilisant CALL WORKER. Notez que le nom du process principal peut varier en fonction de la langue de localisation de 4D, mais qu'il porte toujours le numéro de process 1. Par conséquent, il est plus pratique de le désigner par son numéro de process plutôt que par son nom lors de l'appel à CALL WORKER.

Identifier les process worker

Tous les process worker, à l'exception du process principal, ont le type de process Worker process (5) renvoyé par la commande Process info.

Des icônes spécifiques identifient les process worker.

Voir également

Pour plus d'informations, veuillez consulter cet article de blog sur l'utilisation des workers.

Sémaphores

Les sémaphores vous permettent de vous assurer que deux processus ou plus ne modifient pas la même ressource (fichier, enregistrement...) en même temps. Seul le processus qui pose le sémaphore peut le retirer.

info

Les signaux peuvent également être utilisés pour gérer les interactions. Les signaux vous permettent de vous assurer qu'un ou plusieurs processus attendront qu'une tâche spécifique soit terminée avant de poursuivre leur exécution. Tout processus peut attendre et/ou libérer un signal.

Qu'est-ce qu'un sémaphore ?

Dans un programme informatique, un sémaphore est un outil utilisé pour protéger des actions qui ne doivent être exécutées que par un seul processus ou utilisateur à la fois.

En 4D, le besoin classique d'utiliser des sémaphores concerne la modification d'un tableau interprocess : si un processus modifie les valeurs du tableau, un autre processus ne doit pas pouvoir faire la même chose en même temps. Le développeur utilise un sémaphore pour indiquer à un processus qu'il ne peut effectuer sa séquence d'opérations que si aucun autre processus n'effectue déjà les mêmes tâches. Lorsqu'un processus rencontre un sémaphore, trois possibilités se présentent :

  • Il obtient immédiatement le droit de passer
  • Il attend son tour jusqu'à obtenir le droit de passer
  • Il poursuit son chemin, renonçant à exécuter les tâches.

Le sémaphore protège donc des parties du code. Il ne laisse passer qu'un seul processus à la fois et bloque l'accès jusqu'à ce que le processus détenant actuellement le droit d'utilisation abandonne ce droit en libérant le sémaphore.

Commandes pour travailler avec les sémaphores

En 4D, vous posez un sémaphore en appelant la commande Semaphore. Pour libérer un sémaphore, vous appelez la commande CLEAR SEMAPHORE.

La commande Semaphore a un comportement très particulier car elle effectue potentiellement deux actions simultanément :

  • Si le sémaphore est déjà attribué, la fonction retourne True
  • Si le sémaphore n'est pas attribué, la fonction l'attribue au processus et retourne False en même temps.

Cette double action effectuée par la même commande garantit qu'aucune opération externe ne peut s'insérer entre le test du sémaphore et son attribution.

Vous pouvez utiliser la commande Test semaphore pour savoir si un sémaphore est déjà attribué ou non. Cette commande est principalement utilisée dans le cadre d'opérations longues, telles que la clôture annuelle des comptes, où Test semaphore vous permet de contrôler l'interface afin d'empêcher l'accès à certaines opérations, comme l'ajout de données comptables.

Comment utiliser les sémaphores

Les sémaphores doivent être utilisés selon les principes suivants :

  • Un sémaphore doit être posé et libéré dans la même méthode,
  • L'exécution du code protégé par le sémaphore doit être aussi courte que possible,
  • Le code doit être temporisé au moyen du paramètre tickCount de la commande Semaphore pour attendre la libération du sémaphore.

Voici un code type pour utiliser un sémaphore :

 While(Semaphore("MySemaphore";300))
IDLE
End while
// placer ici le code protégé par le sémaphore
CLEAR SEMAPHORE("MySemaphore")

Un sémaphore qui n'est pas libéré peut bloquer une partie de la base de données. Poser et libérer les sémaphores dans la même méthode permet d'éliminer ce risque.

Minimiser le code protégé par le sémaphore augmente la fluidité de l'application et évite que le sémaphore ne devienne un goulot d'étranglement.

Enfin, l'utilisation du paramètre optionnel tickCount de la commande Semaphore est essentielle pour optimiser l'attente de la libération du sémaphore. Avec ce paramètre, la commande fonctionne de la manière suivante :

  • Le processus attend au maximum le nombre de ticks spécifié (300 dans l'exemple) que le sémaphore soit disponible, sans que l'exécution du code ne passe à la ligne suivante,
  • Si le sémaphore est libéré avant la fin de cette limite, il est immédiatement attribué au processus (Semaphore retourne False) et l'exécution du code reprend,
  • Si le sémaphore n'est pas libéré avant la fin de cette limite, alors l'exécution du code reprend.

La commande priorise également les requêtes en établissant une file d'attente. Ainsi, le premier processus à demander un sémaphore sera le premier à l'obtenir. Notez que le temps d'attente est défini en fonction des spécificités de l'application.

Sémaphores locaux ou globaux

Il existe deux types de sémaphores en 4D : les sémaphores locaux et les sémaphores globaux.

  • Un sémaphore local est accessible par tous les processus du même poste de travail et uniquement sur ce poste. Un sémaphore local peut être créé en préfixant le nom du sémaphore par un signe dollar ($). Vous utilisez les sémaphores locaux pour surveiller les opérations entre des processus s'exécutant sur le même poste de travail. Par exemple, un sémaphore local peut être utilisé pour surveiller l'accès à un tableau interprocess partagé par tous les processus de votre base de données mono-utilisateur ou du poste de travail.
  • Un sémaphore global est accessible à tous les utilisateurs et à tous leurs processus. Vous utilisez les sémaphores globaux pour surveiller les opérations entre les utilisateurs d'une base de données multi-utilisateurs.

Les sémaphores globaux et locaux sont identiques dans leur logique. La différence réside dans leur portée.

En client/serveur, les sémaphores globaux sont partagés entre tous les processus s'exécutant sur tous les clients et serveurs. Un sémaphore local n'est partagé qu'entre les processus s'exécutant sur la machine où il a été créé.

Dans les applications 4D mono-utilisateur, les sémaphores globaux ou locaux ont la même portée car vous êtes le seul utilisateur. Toutefois, si votre base de données est utilisée dans les deux configurations, veillez à utiliser des sémaphores globaux ou locaux selon ce que vous souhaitez faire.

Note : Nous recommandons d'utiliser des sémaphores locaux lorsque vous avez besoin d'un sémaphore pour gérer un aspect local d'un client de l'application, tel que l'interface ou un tableau de variables interprocess. Si vous utilisez un sémaphore global dans ce cas, cela provoquerait non seulement des échanges réseau inutiles, mais pourrait aussi affecter inutilement d'autres machines clientes. L'utilisation d'un sémaphore local éviterait ces effets secondaires indésirables.