Quand est-ce que le pool de threads utilisés?
J'ai donc une compréhension de la façon dont Node.js œuvres: il a un seul thread d'écoute qui reçoit un événement, puis délègue à un pool de travail. Le thread de travail informe l'auditeur une fois qu'il termine le travail, et l'auditeur puis renvoie la réponse à l'appelant.
Ma question est: si je me lève d'un serveur HTTP Node.js et d'appeler le sommeil sur un de mes acheminé chemin événements (tels que "/test/sommeil"), l'ensemble du système est livré à une halte. Même le seul thread d'écoute. Mais ma compréhension est que ce code se passe sur le pool de travail.
Maintenant, par contre, quand j'utilise la Mangouste de parler à MongoDB, DB lectures sont une coûteuse opération d'e/S. Nœud semble être en mesure de déléguer le travail à un fil et recevoir le rappel lorsqu'elle est terminée; le temps nécessaire pour charger à partir de la DB ne semble pas bloquer le système.
Comment Node.js décidez d'utiliser un thread du pool vs le thread d'écoute? Pourquoi ne puis-je pas écrire le code d'événement qui dort et seuls les blocs d'un thread du pool?
- J'ai vu qu'. Ça ne fonctionne toujours pas répondu à ma question. Si le travail a été sur un autre thread, le sommeil ne toucherait que le fil et de ne pas l'auditeur ainsi.
- Une véritable question, où vous essayez de comprendre quelque chose par vous-même, et quand vous ne pouvez pas trouver la sortie du labyrinthe, vous demander de l'aide.
Vous devez vous connecter pour publier un commentaire.
Votre compréhension de la façon fonctionnement du nœud n'est pas correct... mais c'est une idée fausse commune, parce que la réalité de la situation est en fait assez complexe, et généralement se résumait à peu lapidaire des phrases comme "nœud est mono-thread" que la sur-simplifier les choses.
Pour le moment, nous n'en tenons pas compte explicite des multi-processeurs et multi-threading par cluster et webworker-fils, et juste en parler typique non filetée nœud.
Nœud s'exécute en une seule boucle d'événements. Il est mono-thread, et vous ne jamais obtenir qu'un seul thread. Tout le code javascript que vous écrivez s'exécute dans cette boucle, et si une opération de blocage qui se passe dans ce code, il va bloquer la totalité de la boucle et rien d'autre se passe jusqu'à la fin. C'est le seul thread à la nature de nœud que vous entendez beaucoup parler. Mais, ce n'est pas la totalité de l'image.
De certaines fonctions et de modules, généralement écrits en C/C++, le soutien asynchronous I/O. Lorsque vous appelez ces fonctions et méthodes, ils gérer de façon interne de transmettre l'appel à un thread de travail. Par exemple, lorsque vous utilisez le
fs
module à la demande d'un fichier, lefs
module de passe qui appellent à un thread de travail, et que le travailleur attend sa réponse, qu'il présente ensuite retour à la boucle d'événements qui a été barattage sans elle dans l'intervalle. Tout cela est abstrait, loin de vous, le nœud de développeur, et il est soustrait à l'écart du module développeurs par le biais de l'utilisation de libuv.Comme l'a souligné Denis Dollfus dans les commentaires (à partir de cette réponse à une question similaire), la stratégie utilisée par libuv pour atteindre asynchronous I/O n'est pas toujours un pool de threads, en particulier dans le cas de la
http
module une stratégie différente semble être utilisés à cette époque. Pour nos besoins ici, il est surtout important de noter comment le contexte asynchrone est atteint (en utilisant libuv) et que le pool de threads maintenu par libuv est l'une des multiples stratégies proposées par la bibliothèque pour atteindre l'asynchronicité.Sur la plupart liés à la tangente, il y a une analyse beaucoup plus profonde de la façon dont nœud atteint l'asynchronicité, et quelques problèmes potentiels et la façon de traiter avec eux, dans cet excellent article. La plupart, il s'étend sur ce que j'ai écrit ci-dessus, mais en outre, il souligne:
UV_THREADPOOL_SIZE
variable d'environnement, aussi longtemps que vous le faites avant le pool de threads est nécessaire et créé le:process.env.UV_THREADPOOL_SIZE = 10;
Si vous voulez traditionnel multi-processing ou multi-threading dans le nœud, vous pouvez l'obtenir par le biais de la construction dans
cluster
module ou divers autres modules tels que celui-ciwebworker-threads
, ou vous pouvez le faux par la mise en œuvre d'une certaine façon de segmentation de votre travail, et manuellement à l'aide desetTimeout
ousetImmediate
ouprocess.nextTick
pour mettre en pause votre travail et de le continuer plus loin dans la boucle de laisser à d'autres processus complet (mais ce n'est pas recommandé).Veuillez noter que si vous écrivez un long cours d'exécution/de blocage de code en javascript, vous êtes probablement faire une erreur. D'autres langues seront d'effectuer beaucoup plus efficacement.
nodejs
capable de gérer les connexions simultanées, à condition qu'il s'exécute sur un seul fil? Si je reçois1000
demandes simultanées, chacun demande d'être traitées l'une après l'autre? Si oui, sera-il pas être un indésirable retard dans la réponse envoyée à chaque requête? Ce qui va se passer si elle reçoit1000 * 1000
demandes simultanées?cluster
. Deuxièmement, il existe des exemples concrets de personnes atteignant plus de 100 demandes simultanées - à-dire sans décalage. La raison pour laquelle cela fonctionne est parce qu'un écrit correctement le nœud de l'application fera très peu de travail réel dans son un thread, il va passer la plupart du travail asynchrone des modules écrits aveclibuv
. Il peut-être un jour touché 1m demandes, mais rien d'autre n'est à proximité que ce soit.Ce n'est pas vraiment précis. Node.js n'a qu'un seul "travailleur" thread qui n'exécution de javascript. Il y a des threads dans le nœud que la poignée de traitement des e /s, mais à les considérer comme des "travailleurs" est une idée fausse. Il y a vraiment juste IO de manutention et de quelques autres détails de nœud interne de la mise en œuvre, mais en tant que programmeur, vous ne pouvez pas influencer leur comportement d'autre qu'un peu de divers paramètres tels que MAX_LISTENERS.
Il n'existe pas de mécanisme du sommeil en JavaScript. Nous pourrions en discuter plus concrètement, si vous avez posté un extrait de code de ce que vous pensez de "sommeil" signifie. Il n'y a pas une telle fonction à appeler pour simuler quelque chose comme
time.sleep(30)
en python, par exemple. Il y asetTimeout
mais qui est fondamentalement PAS le sommeil.setTimeout
etsetInterval
explicitement libération, ne pas bloquer la boucle d'événement de sorte que les autres bits de code peut s'exécuter sur-le-main thread d'exécution. La seule chose que vous pouvez faire est occupé de la boucle de la CPU avec en mémoire les calculs, ce qui sera de fait mourir de faim les principaux thread d'exécution et de rendre votre programme ne répond pas.Réseau IO est toujours asynchrone. Fin de l'histoire. E /s de disque a la fois synchrone et asynchrone Api, donc il n'y a pas de "décision". node.js va se comporter en fonction de l'API des fonctions de base que vous appelez de synchronisation vs normale asynchrone. Par exemple:
fs.readFile
vsfs.readFileSync
. Pour les processus enfants, il y a aussi l'child_process.exec
etchild_process.execSync
Api.Règle de base est de toujours utiliser l'Api asynchrones. Les raisons valables d'utiliser l'Api de synchronisation sont pour le code d'initialisation dans un réseau de service avant qu'il est à l'écoute pour les connexions ou dans des scripts simples qui n'acceptent pas les demandes de réseau pour construire des outils et ce genre de chose.
fs
, autant que je sacheCe malentendu est simplement la différence entre préférentiel de souscription multi-tâches et le multitâche coopératif...
Le sommeil désactive le carnaval car il y a vraiment une ligne à tous les manèges, et vous avez fermé la porte. Pensez à lui comme "un JS interprète et d'autres choses" et d'ignorer les filets...pour vous, il n'y a qu'un seul thread, ...
...afin de ne pas les bloquer.