Comment créer des threads dans nodejs

91

Existe-t-il un moyen de créer des threads pour exécuter plusieurs méthodes à la fois?

De cette façon, si une méthode échoue entre tous les autres threads doivent être tués.

user87267867
la source

Réponses:

94

Chaque processus node.js est unique par conception. Par conséquent, pour obtenir plusieurs threads, vous devez avoir plusieurs processus (comme l'ont souligné d'autres affiches, il existe également des bibliothèques auxquelles vous pouvez créer un lien qui vous donneront la possibilité de travailler avec des threads dans Node, mais une telle capacité n'existe pas sans ces bibliothèques. . Voir la réponse de Shawn Vincent référençant https://github.com/audreyt/node-webworker-threads )

Vous pouvez démarrer des processus enfants à partir de votre processus principal comme indiqué ici dans la documentation node.js: http://nodejs.org/api/child_process.html . Les exemples sont assez bons sur cette page et sont assez simples.

Votre processus parent peut alors surveiller l'événement de fermeture sur n'importe quel processus qu'il a démarré, puis forcer la fermeture des autres processus que vous avez commencés pour atteindre le type de stratégie d'arrêt unique dont vous parlez.

Voir aussi: Node.js sur les machines multicœurs

Brian
la source
les processus peuvent-ils fonctionner parallèlement et séquentiellement à la fois
user87267867
2
Les processus enfants sont indépendants du processus parent. Ils ont leur propre espace mémoire, PID et temps d'exécution. Je ne sais pas ce que vous entendez par séquentiel, mais oui, ils fonctionneront en parallèle et seront programmés séparément par le système d'exploitation pour l'exécution.
Brian le
comment appeler des fonctions définies par l'utilisateur en tant que processus enfant?
user87267867
Comment puis-je générer un processus enfant pour appeler la fonction abc () {}
user87267867
2
Huh, je n'étais pas au courant de cette bibliothèque, mais il semble que selon le commentaire d'Alex Mills, vous pouvez faire un travail de threading dans Node. Cela étant dit, la question suivante est de savoir si vous. . . Node a été conçu de fond en comble pour libérer les programmeurs de la complexité fournie avec les threads, mais offrant des performances de type similaire pour bloquer les E / S. Je modifierai ma réponse pour tenir compte du fait qu'il est possible d'utiliser la bibliothèque référencée.
Brian
34

Il existe également au moins une bibliothèque pour effectuer des threads natifs à partir de Node.js: node-webworker-threads

https://github.com/audreyt/node-webworker-threads

Cela implémente essentiellement l' API de navigateur Web Worker pour node.js.

Shawn Vincent
la source
3
cela devrait être correct. la réponse suggérant que le nœud ne peut générer que des processus, mais pas des threads, est fausse.
Alexander Mills
9

Vous pouvez obtenir le multi-threading en utilisant Napa.js.

https://github.com/Microsoft/napajs

"Napa.js est un environnement d'exécution JavaScript multithread basé sur la version 8, qui a été initialement conçu pour développer des services hautement itératifs avec des performances non compromises dans Bing. Au fur et à mesure de son évolution, nous trouvons utile de compléter Node.js dans les tâches liées au processeur. , avec la capacité d'exécuter JavaScript dans plusieurs isolats V8 et de communiquer entre eux. Napa.js est exposé en tant que module Node.js, alors qu'il peut également être intégré dans un processus hôte sans dépendance Node.js. "

shmuli
la source
3

J'avais besoin d'un véritable multithreading dans Node.js et ce qui fonctionnait pour moi, c'était le package threads . Il engendre un autre processus ayant sa propre boucle de message Node.js, afin qu'ils ne se bloquent pas. La configuration est simple et la documentation vous permet d'être rapidement opérationnel. Votre programme principal et les ouvriers peuvent communiquer des deux manières et les "threads" de travail peuvent être tués si nécessaire.

Étant donné que le multithreading et Node.js est un sujet compliqué et largement discuté, il était assez difficile de trouver un package qui fonctionne pour mes besoins spécifiques. Pour mémoire, cela n'a pas fonctionné pour moi :

  • tiny-worker permettait de générer des ouvriers, mais ils semblaient partager la même boucle de message (mais il se peut que j'ai fait quelque chose de mal - les threads avaient plus de documentation me donnant l'assurance qu'il utilisait vraiment plusieurs processus, alors j'ai continué jusqu'à ce que cela fonctionne)
  • webworker-threads n'autorisait pas les requiremodules de travail dont j'avais besoin

Et pour ceux qui me demandent pourquoi j'avais besoin d'un vrai multi-threading: pour une application impliquant le Raspberry Pi et les interruptions. Un thread gère ces interruptions et un autre se charge de stocker les données (et plus).

Heinrich Ulbricht
la source
1
J'apprécie la grande réflexion mise dans cette réponse!
MLissCetrus
3

Le nodejs 10.5.0 a annoncé la libération multithreading dans Node.js . La fonctionnalité est encore expérimentale. Un nouveau module worker_threads est maintenant disponible.

Vous pouvez commencer à utiliser des threads de travail si vous exécutez Node.js v10.5.0 ou supérieur , mais il s'agit d'une API expérimentale . Il n'est pas disponible par défaut: vous devez l'activer en utilisant  --experimental-worker lors de l'appel de Node.js.

Voici un exemple avec ES6 et worker_threads activés, testé sur la version 12.3.1

//package.json

  "scripts": {
  "start": "node  --experimental-modules --experimental- worker index.mjs"
  },

Maintenant, vous devez importer Worker depuis worker_threads . Remarque: vous devez déclarer vos fichiers js avec l'extension '.mjs' pour la prise en charge d'ES6.

//index.mjs
import { Worker } from 'worker_threads';

const spawnWorker = workerData => {
    return new Promise((resolve, reject) => {
        const worker = new Worker('./workerService.mjs', { workerData });
        worker.on('message', resolve);
        worker.on('error', reject);
        worker.on('exit', code => code !== 0 && reject(new Error(`Worker stopped with 
        exit code ${code}`)));
    })
}

const spawnWorkers = () => {
    for (let t = 1; t <= 5; t++)
        spawnWorker('Hello').then(data => console.log(data));
}

spawnWorkers();

Enfin, nous créons un workerService.mjs

//workerService.mjs
import { workerData, parentPort, threadId } from 'worker_threads';

// You can do any cpu intensive tasks here, in a synchronous way
// without blocking the "main thread"
parentPort.postMessage(`${workerData} from worker ${threadId}`);

Production:

npm run start

Hello from worker 4
Hello from worker 3
Hello from worker 1
Hello from worker 2
Hello from worker 5
priyeshdkr
la source
2
Est-ce votre article: blog.logrocket.com / ... ?
serv-inc
Non ... ce n'est pas ... Je l'ai renvoyé dans le temps.
priyeshdkr
2

NodeJS inclut désormais les threads (en tant que fonctionnalité expérimentale au moment de la réponse).

James Holmes
la source
0

Vous recherchez peut-être Promise.race(solution de course E / S native, pas de threads)

En supposant que vous (ou d'autres personnes à la recherche de cette question) vouliez lancer des threads pour éviter les échecs et éviter le coût des opérations d'E / S, c'est une manière simple et native de l'accomplir (qui n'utilise pas de threads). Le nœud est conçu pour être à thread unique (recherchez la boucle d'événements), évitez donc d'utiliser des threads si possible. Si mon hypothèse est correcte, je vous recommande d'utiliser Promise.raceavec setTimeout(exemple en lien). Avec cette stratégie, vous courriez une liste de promesses qui essaient chacune une opération d'E / S et rejetteraient la promesse s'il y a une erreur (sinon timeout). La Promise.racedéclaration continue après la première résolution / rejet, ce qui semble être ce que vous voulez. J'espère que cela aide quelqu'un!

smileham
la source
2
Cela n'a rien à voir avec les threads. Ils fonctionnent tous dans le même fil.
Evan Carroll
@EvanCarroll - Merci de m'avoir alerté que je n'étais pas assez clair. Je l'ai précédé d'une hypothèse sur la raison pour laquelle quelqu'un pourrait rechercher des courses de threads et j'ai noté que cela utilise des promesses dans la boucle d'événements de Node. Venant d'un autre langage, il est très possible que vous souhaitiez accomplir ce que font les threads mais que vous ne soyez pas encore familier avec la boucle d'événements ou les promesses. Je voulais noter qu'il existe des moyens plus simples d'accomplir cela si tel est votre objectif. J'ai ajouté une parenthèse que cela n'utilise pas de threads. Faites-moi savoir si cela clarifie les choses.
smileham
Il semble également répondre aux critères des OP: "Si une méthode échoue entre tous les autres threads devraient être tués", j'ai donc pensé que c'était pertinent.
smileham
Promise.race exécute toutes les promesses de manière séquentielle, passant de l'une à l'autre en cas d'opération asynchrone (ou en attente en cas de fonction asynchrone).
Nagabhushan Baddi
0

Node.js n'utilise pas de thread. Selon son inventeur, c'est une caractéristique clé. Au moment de son invention, les fils étaient lents, problématiques et difficiles. Node.js a été créé à la suite d'une enquête sur une alternative efficace à un seul cœur. La plupart des passionnés de Node.js citent encore votre ancien argument comme si les threads n'avaient pas été améliorés au cours des 50 dernières années.

Comme vous le savez, Node.js est utilisé pour exécuter JavaScript. Le langage JavaScript s'est également développé au fil des ans. Il a maintenant des moyens d'utiliser plusieurs cœurs - c'est-à-dire ce que font les threads. Ainsi, grâce aux progrès de JavaScript, vous pouvez effectuer du multitâche multi-cœur dans vos applications. user158 souligne que Node.js joue un peu avec lui. Je n'en sais rien. Mais pourquoi attendre que Node.js approuve ce que JavaScript a à offrir.

Google pour le multi-threading JavaScript au lieu du multi-threading Node.js. Vous découvrirez les Web Workers, les promesses et d'autres choses.

Roger F. Gay
la source