


Comment comprendre que Node.js n'est pas un programme entièrement monothread (une brève analyse)
Pourquoi disons-nous que Node.js n'est pas complètement monothread ? Comment comprendre ? L’article suivant en discutera avec vous, j’espère qu’il vous sera utile !
Je crois que tout le monde sait que node est un programme monothread qui utilise Event Loop pour obtenir plusieurs simultanéités. Malheureusement, ce n'est pas tout à fait exact.
Alors pourquoi Node.js n'est-il pas un programme entièrement monothread ?
Node.js est un programme à thread unique*
Toutes les boucles Javsacript, V8 et d'événements que nous avons nous-mêmes écrites s'exécutent dans le même thread, qui est le thread principal.
Hé, cela ne signifie-t-il pas que ce nœud est monothread ?
Mais peut-être que vous ne savez pas que ce nœud contient de nombreux modules avec du code C++ derrière eux.
Bien que le nœud n'expose pas les utilisateurs à l'autorisation de contrôler les threads, C++ peut utiliser le multi-threading.
Alors, quand node utilisera-t-il le multi-threading ?
Si une méthode de nœud appelle la méthode synchronisation de C++ en arrière-plan, tout s'exécutera dans le thread principal.
Si une méthode de nœud appelle la méthode asynchrone de C++ en arrière-plan, parfois elle ne s'exécute pas dans le thread principal.
Talk n'est pas cher, montre-moi le code
Méthode synchrone, exécutée dans le thread principal
Ici crypto
Modules associés, beaucoup sont écrits en C++. Le programme suivant est une fonction de calcul de hachage, généralement utilisée pour stocker les mots de passe.
import { pbkdf2Sync } from "crypto"; const startTime = Date.now(); let index = 0; for (index = 0; index < 3; index++) { pbkdf2Sync("secret", "salt", 100000, 64, "sha512"); const endTime = Date.now(); console.log(`${index} time, ${endTime - startTime}`); } const endTime = Date.now(); console.log(`in the end`);
Temps de sortie,
0 time, 44 1 time, 90 2 time, 134 in the end
peut être vu que cela prend environ 45 ms à chaque fois et que le code est exécuté séquentiellement sur le thread principal.
Faites attention à qui est le résultat final ? Notez qu'un hachage prend ici environ 45 ms sur mon processeur.
La méthode asynchrone pbkdf2 ne s'exécute pas dans le thread principal
import { cpus } from "os"; import { pbkdf2 } from "crypto"; console.log(cpus().length); let startTime = console.time("time-main-end"); for (let index = 0; index < 4; index++) { startTime = console.time(`time-${index}`); pbkdf2("secret", `salt${index}`, 100000, 64, "sha512", (err, derivedKey) => { if (err) throw err; console.timeEnd(`time-${index}`); }); } console.timeEnd("time-main-end");
Le temps de sortie,
time-main-end: 0.31ms time-2: 45.646ms time-0: 46.055ms time-3: 46.846ms time-1: 47.159ms
Comme vous pouvez le voir ici, le thread principal se termine plus tôt, mais chaque temps de calcul est de 45 ms. Le processeur calcule le hachage. Le temps est de 45 ms. Le nœud ici utilise définitivement plusieurs threads pour le calcul du hachage.
Si je change le nombre d'appels ici à 10, alors le temps est le suivant. Vous pouvez voir qu'à mesure que le nombre de cœurs de processeur est utilisé, le temps augmente également. Une fois de plus, il est prouvé que le nœud utilise définitivement plusieurs threads pour le calcul du hachage.
time-main-end: 0.451ms time-1: 44.977ms time-2: 46.069ms time-3: 50.033ms time-0: 51.381ms time-5: 96.429ms // 注意这里,从第五次时间开始增加了 time-7: 101.61ms time-4: 113.535ms time-6: 121.429ms time-9: 151.035ms time-8: 152.585ms
Bien qu'il soit prouvé ici que le multi-threading est définitivement activé sur le nœud. Mais il y a un petit problème ? Le processeur de mon ordinateur est AMD R5-5600U, doté de 6 cœurs et 12 threads. Mais pourquoi le temps augmente-t-il à partir de la cinquième fois ? Le nœud n’utilise pas pleinement mon processeur ?
Quelle est la raison ?
Node utilise un pool de threads prédéfini. La taille par défaut de ce pool de threads est 4.
export UV_THREADPOOL_SIZE=6
Regardons un exemple,
Requête HTTP
import { request } from "https"; const options = { hostname: "www.baidu.com", port: 443, path: "/img/PC_7ac6a6d319ba4ae29b38e5e4280e9122.png", method: "GET", }; let startTime = console.time(`main`); for (let index = 0; index < 15; index++) { startTime = console.time(`time-${index}`); const req = request(options, (res) => { console.log(`statusCode: ${res.statusCode}`); console.timeEnd(`time-${index}`); res.on("data", (d) => { // process.stdout.write(d); }); }); req.on("error", (error) => { console.error(error); }); req.end(); } console.timeEnd("main");
main: 13.927ms time-2: 83.247ms time-4: 89.641ms time-3: 91.497ms time-12: 91.661ms time-5: 94.677ms ..... time-8: 134.026ms time-1: 143.906ms time-13: 140.914ms time-10: 144.088ms
Le programme principal ici est Cela s'est également terminé plus tôt. Ici, j'ai lancé la requête http pour télécharger des images 15 fois. Le temps nécessaire n'a pas augmenté de façon exponentielle et ne semblait pas être limité par le pool de threads/le processeur.
Pourquoi ? ? Node utilise-t-il un pool de threads ?
Si la méthode C++ asynchrone derrière Node, elle essaiera d'abord de voir s'il existe un support asynchrone du noyau. Par exemple, veuillez utiliser epoll (Linux) pour le réseau ici. Si le noyau ne fournit pas de méthode asynchrone, Node. utilisera son propre pool de threads. .
Ainsi, bien que la requête http soit asynchrone, elle est implémentée par le noyau lorsque le noyau est terminé, C++ en sera informé et C++ notifiera au thread principal de gérer le rappel.
Alors, quelles méthodes asynchrones dans Node utilisent le pool de threads ? Lesquels ne le feront pas ?
-
Native Kernal Async
- Client serveur TCP/UDP
- Unix Domain Sockets (IPC)
- pipes
- dns.resolveXXX
- tty input (stdin etc)
- Signaux Unix
- Processus enfant
-
Thread pool
- fs.*
- dns.lookup
- pipe (edge case)
C'est également le point d'entrée pour la plupart des optimisations de nœuds.
Mais comment ceux-ci se combinent-ils avec la boucle d'événement la plus importante ?
Event Loop
Je pense que tout le monde connaît très bien Event Loop. La boucle d'événements est comme un distributeur.
Si elle rencontre un programme javascript ordinaire ou un rappel, elle est transmise à V8 pour traitement.
Si vous rencontrez une méthode synchronisée écrite en C++, remettez-la en C++ et exécutez-la sur le thread principal.
Si vous rencontrez une méthode asynchrone, le verso est écrit en C++. S'il existe un support asynchrone du noyau, transmettez-le du thread principal au noyau pour traitement.
Si elle est asynchronele dos de la méthode est écrit en C++ S'il n'y a pas de support asynchrone par le noyau, elle est transmise du thread principal au pool de threads.
Le pool de threads et le noyau renverront les résultats à la boucle d'événements. Si un rappel javascript est enregistré, il sera transmis à la V8 pour traitement.
Ensuite, le cycle continue jusqu'à ce qu'il n'y ait plus rien à traiter.
Donc, Node n'est pas exactement un programme monothread.
Pour plus de connaissances sur les nœuds, veuillez visiter : tutoriel Nodejs !
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!

Outils d'IA chauds

Undresser.AI Undress
Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover
Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool
Images de déshabillage gratuites

Clothoff.io
Dissolvant de vêtements AI

Video Face Swap
Échangez les visages dans n'importe quelle vidéo sans effort grâce à notre outil d'échange de visage AI entièrement gratuit !

Article chaud

Outils chauds

Bloc-notes++7.3.1
Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise
Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1
Puissant environnement de développement intégré PHP

Dreamweaver CS6
Outils de développement Web visuel

SublimeText3 version Mac
Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Cet article vous donnera une compréhension approfondie de la mémoire et du garbage collector (GC) du moteur NodeJS V8. J'espère qu'il vous sera utile !

Le service Node construit sur une base non bloquante et piloté par les événements présente l'avantage d'une faible consommation de mémoire et est très adapté à la gestion de requêtes réseau massives. Dans le contexte de demandes massives, les questions liées au « contrôle de la mémoire » doivent être prises en compte. 1. Le mécanisme de récupération de place du V8 et les limitations de mémoire Js sont contrôlés par la machine de récupération de place

Le choix d'une image Docker pour Node peut sembler trivial, mais la taille et les vulnérabilités potentielles de l'image peuvent avoir un impact significatif sur votre processus CI/CD et votre sécurité. Alors, comment choisir la meilleure image Docker Node.js ?

Le module de fichiers est une encapsulation des opérations de fichiers sous-jacentes, telles que l'ajout de lecture/écriture/ouverture/fermeture/suppression de fichiers, etc. La plus grande caractéristique du module de fichiers est que toutes les méthodes fournissent deux versions de **synchrone** et ** asynchrone**, with Les méthodes avec le suffixe sync sont toutes des méthodes de synchronisation, et celles qui n'en ont pas sont toutes des méthodes hétérogènes.

Node 19 est officiellement publié. Cet article vous donnera une explication détaillée des 6 fonctionnalités majeures de Node.js 19. J'espère qu'il vous sera utile !

Comment Node.js fait-il le GC (garbage collection) ? L’article suivant vous guidera à travers cela.

La boucle d'événements est un élément fondamental de Node.js et permet une programmation asynchrone en garantissant que le thread principal n'est pas bloqué. Comprendre la boucle d'événements est crucial pour créer des applications efficaces. L'article suivant vous donnera une compréhension approfondie de la boucle d'événements dans Node. J'espère qu'il vous sera utile !

La raison pour laquelle le nœud ne peut pas utiliser la commande npm est que les variables d'environnement ne sont pas configurées correctement. La solution est la suivante : 1. Ouvrez "Propriétés système" ; 2. Recherchez "Variables d'environnement" -> "Variables système", puis modifiez l'environnement. variables ; 3. Recherchez l'emplacement du dossier nodejs ; 4. Cliquez sur "OK".
