Maison  >  Article  >  interface Web  >  Une analyse approfondie du multi-threading et du multi-traitement dans Node.js

Une analyse approfondie du multi-threading et du multi-traitement dans Node.js

青灯夜游
青灯夜游avant
2020-08-31 09:55:192571parcourir

Une analyse approfondie du multi-threading et du multi-traitement dans Node.js

Node.js est un environnement d'exécution JavaScript multiplateforme gratuit Bien qu'il soit de nature monothread, il peut utiliser plusieurs threads en arrière-plan pour exécuter. code asynchrone.

En raison de la nature non bloquante de Node.js, différents threads exécutent différents rappels, qui sont d'abord délégués à la boucle d'événements. Le runtime Node.js gère tout cela. [Recommandation tutoriel vidéo : tutoriel node js]

Pourquoi utiliser NodeJS ?

JavaScript a été conçu à l'origine comme un langage de programmation monothread qui ne fonctionnait que dans un navigateur Web. Cela signifie qu’au sein d’un processus, un seul ensemble d’instructions peut être exécuté à un instant donné.

Passez au bloc de code suivant uniquement une fois l'exécution du bloc de code actuel terminée. Cependant, la nature monothread de JavaScript facilite la mise en œuvre.

À l'origine, JavaScript n'était utilisé que pour ajouter une petite quantité d'interactivité à un site Web. Il n’y a donc pas besoin de multi-thread. Mais les temps ont changé, les utilisateurs sont devenus plus exigeants et JavaScript est devenu « le langage de programmation le plus populaire sur le Web ».

Les discussions multiples deviennent courantes de nos jours. Étant donné que JavaScript est un langage monothread, le multithreading ne peut pas y être implémenté. Heureusement, dans ce cas, il existe une excellente solution : Node.js. Les

Les frameworks Node.js ne manquent pas, grâce à la popularité des environnements d'exécution JavaScript en général et JavaScript en particulier. Avant de continuer cet article, comprenons quelques points importants à propos de Node.js :

  1. Vous pouvez utiliser la fonction d'envoi pour transmettre des messages des processus enfants à d'autres processus enfants et au processus principal
  2. Plusieurs processus Fork pris en charge
  3. Aucun état n'est partagé entre le processus principal et le processus enfant

Pourquoi fork le processus ?

Dans deux cas, nous devons bifurquer un processus :

  1. Pour augmenter la vitesse en déléguant des tâches à d'autres processus
  2. Pour libérer de la mémoire et décharger un seul processus

peut envoyer des données au processus enfant et peut également les renvoyer.

La méthode Node.js

Node.js utilise deux types de threads :

  1. Le thread principal gère le
  2. travail via un événement loop Il existe de nombreux threads de travail dans le pool

La boucle d'événements est chargée d'obtenir des rappels ou des fonctions et de les enregistrer pour une exécution future. Il s'exécute dans le même thread que le code JavaScript correct. Une fois qu'une opération JavaScript bloque le thread, la boucle d'événements est également bloquée.

Le pool de travail est un modèle d'exécution responsable de la génération et du traitement de différents threads. Il exécute la tâche de manière synchrone, puis renvoie le résultat à la boucle d'événements, et enfin la boucle d'événements fournit le résultat au rappel.

En résumé, le pool de travailleurs est responsable des opérations d'E/S asynchrones, c'est-à-dire des interactions avec le disque système et le réseau. Des modules comme fs et crypto sont les principaux modules qui utilisent des pools de travailleurs.

Étant donné que le pool de travailleurs est implémenté dans la bibliothèque libuv, Node.js a un léger retard dans la communication interne entre JS et C++. Mais c'est presque imperceptible.

Tout allait bien jusqu'à ce que nous soyons confrontés à la nécessité d'effectuer des opérations complexes de manière synchrone. Toute fonction dont l'exécution prend beaucoup de temps entraînera le blocage du thread principal.

Si un programme possède plusieurs fonctions gourmandes en CPU, cela entraînera une baisse significative du débit du serveur. Dans le pire des cas, le serveur ne répondra plus et ne pourra plus déléguer des tâches au pool de travailleurs.

Les domaines tels que l'IA, le Big Data et le Machine Learning ne peuvent pas bénéficier de Node.js car ces opérations bloquent le thread principal et empêchent le serveur de répondre. Mais cela change avec l'arrivée de Node.js v10.5.0, qui ajoute la prise en charge du multi-threading.

Les défis de la concurrence et des tâches liées au processeur

Construire la concurrence en JavaScript peut être difficile. Autoriser plusieurs threads à accéder à la même mémoire peut conduire à des conditions de concurrence qui rendent non seulement l'échec difficile à reproduire, mais également à résoudre.

Node.js a été initialement implémenté en tant que plate-forme côté serveur basée sur des E/S asynchrones. Cela rend beaucoup de choses plus faciles en éliminant simplement le besoin de threads. Oui, les programmes Node.js sont monothread, mais pas de la manière habituelle.

Nous pouvons exécuter en parallèle dans Node.js, mais il n'est pas nécessaire de créer des threads. Le système d'exploitation et la machine virtuelle fonctionnent ensemble pour utiliser les E/S en parallèle, puis lorsque les données doivent être renvoyées au code JavaScript, le code JS s'exécute dans un seul thread.

Tout sauf le code JS s'exécute en parallèle dans Node.js. Contrairement aux blocs asynchrones, les blocs synchrones dans JS sont toujours exécutés une fois à la fois. Attendre que les événements d'E/S se produisent dans JS prend beaucoup plus de temps que l'exécution de code.

Les programmes Node.js appellent uniquement les fonctions ou rappels requis sans bloquer l'exécution d'autres codes. Initialement, ni JavaScript ni Node.js n'étaient destinés à gérer des tâches gourmandes en CPU ou liées au CPU.

Lorsque le code est minimal, l'exécution sera agile. Mais plus la quantité de calcul est importante, plus la vitesse d’exécution est lente.

Si vous essayez toujours d'effectuer des tâches gourmandes en CPU dans JS et Node, vous gelerez l'interface utilisateur dans le navigateur et mettrez en file d'attente tous les événements d'E/S. Pourtant, nous avons parcouru un long chemin. Il existe maintenant le module worker_threads.

Le module Worker_threads facilite le multithreading

Node.js v10.5.0 a été publié en juin 2018, introduisant le module Worker_threads. Il permet d'obtenir la simultanéité dans les environnements d'exécution JavaScript populaires. Ce module permet la création d'applications Node.js multithread entièrement fonctionnelles.

Techniquement parlant, un thread de travail est un code généré dans un thread séparé. Pour commencer à utiliser les threads de travail, vous devez d'abord importer le module worker_threads. Vous devez ensuite créer une instance de la classe Worker pour créer un thread de travail.

Lors de la création d'une instance de la classe Worker, il y a deux paramètres :

  1. Le premier paramètre fournit le chemin d'accès à un fichier d'extension .js ou .mjs qui contient le code pour le thread de travail,
  2. Le deuxième paramètre fournit un objet contenant la propriété workerData, qui contient les données qui seront accessibles lorsque le thread de travail commencera à s'exécuter

Le thread de travail est capable. pour planifier plusieurs événements de message. Par conséquent, les méthodes de rappel ont priorité sur le retour des promesses.

La communication entre les threads de travail est basée sur les événements, c'est-à-dire que l'écouteur est configuré pour être appelé immédiatement après que le thread de travail envoie un événement. Les 4 événements les plus courants sont :

worker.on('error', (error) => {});
  1. Émis lorsqu'il y a une exception non interceptée dans le thread de travail. Ensuite, le thread de travail se termine et l'erreur est disponible comme premier argument dans le rappel.
worker.on('exit', (exitCode) => {})
  1. Émis à la sortie du thread secondaire. Si process.exit() est appelé dans un thread de travail, le exitCode sera fourni au rappel. Code 1 si worker.terminate() termine le thread de travail.
worker.on('message', (data) => {});
  1. Émis lorsque le thread de travail envoie des données au thread parent.
worker.on('online', () => {});
  1. Émis lorsque le thread de travail arrête d'analyser le code JS et commence à s'exécuter. Bien qu’il ne soit pas couramment utilisé, l’événement en ligne peut fournir davantage d’informations dans certaines situations.

Façons d'utiliser les threads de travail

Il existe deux façons d'utiliser les threads de travail :

  • Méthode 1 – implique de générer du travail Thread qui exécute son code et envoie les résultats au thread parent. Cette méthode nécessite de créer un nouveau thread de travail à partir de zéro à chaque fois pour une nouvelle tâche.
  • Méthode 2 – Implique la création d'un fil de travail et la configuration d'écouteurs pour les événements de message. Chaque fois que le message est déclenché, le thread de travail exécute le code et renvoie les résultats au thread parent. Le thread de travail est conservé en vie pour une utilisation ultérieure.

La méthode 2 est également connue sous le nom de pool de travailleurs. En effet, la méthode implique de créer un pool de travailleurs, de les laisser attendre et de distribuer des événements de message pour effectuer des tâches en cas de besoin.

Étant donné que la création d'un thread de travail à partir de zéro nécessite la création d'une machine virtuelle ainsi que l'analyse et l'exécution de code, la documentation officielle de Node.js recommande l'approche 2. De plus, la méthode 2 est plus pratique et plus efficace que la méthode 1.

Propriétés importantes disponibles dans le module worker_threads

  • isMainThread – Cette propriété est vraie lorsqu'elle ne fonctionne pas dans un thread de travail. Si vous le souhaitez, vous pouvez inclure une simple instruction if au début du fichier de travail. Cela garantit qu'il s'exécute uniquement en tant que thread de travail.
  • parentPort – Une instance de MessagePort utilisée pour communiquer avec le thread parent.
  • threadId – Identifiant unique attribué au thread de travail.
  • workerData – Données contenues dans le constructeur du thread de travail.

Processus multiples dans Node.js

Afin que Node.js puisse profiter des capacités des systèmes multicœurs, certains processus peuvent être utilisés. L'environnement d'exécution JavaScript populaire dispose d'un module appelé cluster qui prend en charge plusieurs processus.

Utilisez le module cluster pour générer plusieurs processus enfants, qui peuvent partager un port commun. Les systèmes utilisant NodeJS peuvent gérer des charges de travail plus importantes lorsque des processus enfants sont utilisés.

Node.js sur le backend

Internet est devenu la plateforme de choix pour des millions d'entreprises à travers le monde. Par conséquent, pour qu’une entreprise atteigne son potentiel maximum et se démarque, il est nécessaire d’avoir une forte présence en ligne.

Tout commence par un site Web puissant et intuitif. Pour créer un site internet impeccable, il est important de choisir les meilleures technologies front-end et back-end. Bien que de nature monothread, Node.js est le choix préféré pour développer des services Web back-end.

Malgré la pléthore d'options multithreading backend, les grandes entreprises préfèrent Node.js. En effet, Node.js propose des solutions de contournement pour l'utilisation du multithreading dans JavaScript, qui est déjà « le langage de programmation le plus populaire sur le Web ».

Résumé

Le module worker_threads fournit un moyen simple d'implémenter le multi-threading dans les programmes Node.js. En déléguant des calculs lourds aux threads de travail, vous pouvez augmenter considérablement le débit de votre serveur.

Grâce à la prise en charge du multithreading, Node.js continuera d'attirer un nombre croissant de développeurs, d'ingénieurs et d'autres professionnels issus de domaines à forte intensité de calcul tels que l'IA, le big data et l'apprentissage automatique.

Adresse originale en anglais : https://flatlogic.com/blog/multi-threading-and-multiple-process-in-node-js/

Pour garantir la lisibilité Sex, cet article adopte une traduction libre plutôt qu'une traduction littérale.

Pour plus de connaissances liées à la programmation, veuillez visiter : Enseignement de la programmation ! !

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer