Cómo crear hilos en nodejs

Respuestas:

94

Cada proceso de node.js tiene un solo hilo por diseño. Por lo tanto, para obtener múltiples subprocesos, debe tener múltiples procesos (como han señalado algunos otros carteles, también hay bibliotecas a las que puede vincular que le darán la capacidad de trabajar con subprocesos en Node, pero no existe tal capacidad sin esas bibliotecas . Ver la respuesta de Shawn Vincent haciendo referencia a https://github.com/audreyt/node-webworker-threads )

Puede iniciar procesos secundarios desde su proceso principal como se muestra aquí en la documentación de node.js: http://nodejs.org/api/child_process.html . Los ejemplos son bastante buenos en esta página y son bastante sencillos.

Su proceso principal puede observar el evento de cierre en cualquier proceso que haya iniciado y luego podría forzar el cierre de los otros procesos que comenzó para lograr el tipo de estrategia de parada total de la que está hablando.

Consulte también: Node.js en máquinas de varios núcleos

Brian
fuente
los procesos pueden ejecutarse en paralelo y secuencial a la vez?
user87267867
2
Los procesos secundarios son independientes del proceso principal. Tienen su propio espacio de memoria, PID y tiempo de ejecución. No estoy seguro de lo que quiere decir con secuencial, pero sí, se ejecutarán en paralelo y el sistema operativo los programará por separado para su ejecución.
Brian
¿Cómo llamar a funciones definidas por el usuario como proceso hijo?
user87267867
¿Cómo puedo generar un proceso secundario para llamar a la función abc () {}
user87267867
2
Eh, no estaba al tanto de esa biblioteca, pero parece que, según el comentario de Alex Mills, puedes hacer un trabajo de subprocesamiento en Node. Dicho esto, la siguiente pregunta es si debería. . . Node fue diseñado desde cero para liberar a los programadores de la complejidad que viene con los subprocesos, pero producen un rendimiento de tipo similar para bloquear E / S. Editaré mi respuesta para tener en cuenta el hecho de que es posible usar la biblioteca referenciada.
Brian
9

Puede obtener subprocesos múltiples usando Napa.js.

https://github.com/Microsoft/napajs

"Napa.js es un tiempo de ejecución de JavaScript de subprocesos múltiples construido en V8, que fue diseñado originalmente para desarrollar servicios altamente iterativos con un rendimiento no comprometido en Bing. A medida que evoluciona, nos resulta útil complementar Node.js en tareas vinculadas a la CPU , con la capacidad de ejecutar JavaScript en múltiples aislamientos V8 y comunicarse entre ellos. Napa.js se expone como un módulo Node.js, mientras que también puede integrarse en un proceso de host sin dependencia de Node.js ".

shmuli
fuente
3

Necesitaba un subproceso múltiple real en Node.js y lo que funcionó para mí fue el paquete de subprocesos . Genera otro proceso que tiene su propio bucle de mensajes Node.js, por lo que no se bloquean entre sí. La configuración es fácil y la documentación lo pone en funcionamiento rápidamente. Su programa principal y los trabajadores pueden comunicarse de ambas formas y los "hilos" de los trabajadores pueden eliminarse si es necesario.

Dado que el multiproceso y Node.js es un tema complicado y ampliamente discutido, fue bastante difícil encontrar un paquete que funcionara para mi requisito específico. Para que conste, estos no funcionaron para mí :

  • tiny-worker permitió la generación de trabajadores, pero parecían compartir el mismo bucle de mensajes (pero podría ser que hice algo mal: los hilos tenían más documentación que me daba confianza de que realmente usaba múltiples procesos, así que seguí hasta que funcionó)
  • webworker-threads no permitía requiremódulos -ing en los trabajadores que necesitaba

Y para aquellos que preguntan por qué necesitaba un subproceso múltiple real : para una aplicación que involucra Raspberry Pi e interrupciones. Un hilo maneja esas interrupciones y otro se encarga de almacenar los datos (y más).

Heinrich Ulbricht
fuente
1
¡Aprecio el gran pensamiento puesto en esta respuesta!
MLissCetrus
3

El nodejs 10.5.0 liberación ha anunciado multithreading en Node.js . La función aún es experimental. Hay un nuevo módulo worker_threads disponible ahora.

Puede comenzar a usar subprocesos de trabajo si ejecuta Node.js v10.5.0 o superior , pero esta es una API experimental . No está disponible de forma predeterminada: debe habilitarlo usando  --experimental-worker al invocar Node.js.

Aquí hay un ejemplo con ES6 y worker_threads habilitados, probado en la versión 12.3.1

//package.json

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

Ahora, necesita importar Worker desde worker_threads . Nota: Debe declarar sus archivos js con la extensión '.mjs' para el soporte de 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();

Finalmente, creamos 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}`);

Salida:

npm run start

Hello from worker 4
Hello from worker 3
Hello from worker 1
Hello from worker 2
Hello from worker 5
priyeshdkr
fuente
2
¿Es este su artículo: blog.logrocket.com/… ?
serv-inc
No ... no es ... aunque lo remití en el tiempo.
priyeshdkr
2

NodeJS ahora incluye hilos (como una característica experimental al momento de responder).

James Holmes
fuente
0

Es posible que esté buscando Promise.race(solución de carreras de E / S nativa, no hilos)

Suponiendo que usted (u otras personas que busquen esta pregunta) quieran acelerar los subprocesos para evitar fallas y evitar el costo de las operaciones de E / S, esta es una forma simple y nativa de lograrlo (que no usa subprocesos). El nodo está diseñado para ser de un solo hilo (busque el bucle de eventos), así que evite el uso de hilos si es posible. Si mi suposición es correcta, le recomiendo que use Promise.racecon setTimeout(ejemplo en el enlace). Con esta estrategia, compite con una lista de promesas, cada una de las cuales intenta alguna operación de E / S y rechaza la promesa si hay un error (de lo contrario, se agota el tiempo de espera). La Promise.racedeclaración continúa después de la primera resolución / rechazo, que parece ser lo que desea. ¡Espero que esto ayude a alguien!

smileham
fuente
2
Esto no tiene nada que ver con los hilos. Todos corren en el mismo hilo.
Evan Carroll
@EvanCarroll - Gracias por alertarme de que no fui lo suficientemente claro. Lo precedí con una suposición sobre por qué alguien podría estar buscando carreras de hilos y noté que esto usa promesas en el ciclo de eventos de Node. Viniendo de otro idioma, es muy posible que desee lograr lo que hacen los hilos, pero aún no está familiarizado con el ciclo de eventos o las promesas. Quería señalar que hay formas más sencillas de lograrlo si ese es tu objetivo. Agregué un paréntesis de que esto no usa hilos. Avísame si esto aclara las cosas.
smileham
También parece responder a los criterios de los OP: "Si algún método falla entre todos los demás subprocesos, debe eliminarse", así que pensé que era relevante.
smileham
Promise.race ejecuta todas las promesas secuencialmente, cambiando de una a otra en caso de una operación asincrónica (o en espera en caso de una función asincrónica).
Nagabhushan Baddi
0

Node.js no usa subprocesos. Según su inventor, esa es una característica clave. En el momento de su invención, los hilos eran lentos, problemáticos y difíciles. Node.js se creó como resultado de una investigación sobre una alternativa eficiente de un solo núcleo. La mayoría de los entusiastas de Node.js todavía citan su antiguo argumento como si los hilos no se hubieran mejorado en los últimos 50 años.

Como sabe, Node.js se usa para ejecutar JavaScript. El lenguaje JavaScript también se ha desarrollado a lo largo de los años. Ahora tiene formas de usar múltiples núcleos, es decir, lo que hacen los subprocesos. Por lo tanto, a través de los avances en JavaScript, puede realizar varias tareas múltiples en sus aplicaciones. user158 señala que Node.js está jugando un poco con él. No sé nada de eso. Pero, ¿por qué esperar a que Node.js apruebe lo que JavaScript tiene para ofrecer?

Google for JavaScript multi-threading en lugar de multi-threading de Node.js. Descubrirás sobre Web Workers, Promises y otras cosas.

Roger F. Gay
fuente