Módulo worker_threads de Node.js

Java FileMódulos integrados de Node.js


de Node.jsworker_threadsEl módulo permite a los desarrolladores crear múltiples hilos en aplicaciones Node.js. A diferencia del modelo tradicional de un solo hilo de Node.js, este módulo le permite ejecutar código JavaScript en hilos separados, logrando así un verdadero procesamiento en paralelo.

¿Por qué se necesitan múltiples hilos?

Node.js es de un solo hilo por defecto, lo que significa:

  1. Las tareas intensivas en CPU bloquean el bucle de eventos
  2. No se puede aprovechar plenamente el rendimiento de la CPU multinúcleo
  3. Los cálculos de larga duración reducen la velocidad de respuesta de la aplicación

worker_threadsEl módulo resuelve estos problemas y le permite transferir tareas de uso intensivo de CPU a otros hilos.


Conceptos básicos

Hilo principal vs hilo de trabajo

  1. Hilo principal: el hilo de ejecución principal de la aplicación, responsable de crear y gestionar los hilos de trabajo
  2. Hilo de trabajo: hilo de ejecución independiente creado por el hilo principal para realizar tareas específicas

Comunicación entre hilos

Los hilos de trabajo se comunican con el hilo principal mediante el paso de mensajes en lugar de memoria compartida. Este enfoque evita complejos problemas de sincronización.


API principal

Componentes principales del módulo worker_threads

Ejemplo

const {
  Worker,          // Clase para crear nuevos hilos
  isMainThread,    // Determina si actualmente está en el hilo principal
  parentPort,      // Se utiliza para comunicarse con el hilo padre
  workerData       // Datos pasados al crear el hilo
} = require('worker_threads');

Ejemplo de uso

Crear un hilo de trabajo simple

Código del hilo principal (main.js):

Ejemplo

const { Worker, isMainThread } = require('worker_threads');

if (isMainThread) {
  // Código del hilo principal
  console.log(Este es el hilo principal);
 
  // Crear un hilo de trabajo
  const worker = new Worker('./worker.js', {
    workerData: {
      message: ¡Hola, hilo de trabajo!
    }
  });
 
  // Escuchar los mensajes del hilo de trabajo
  worker.on('message', (msg) => {
    console.log(Recibido del hilo de trabajo: ${msg}`);
  });
 
  worker.on('error', (err) => {
    console.error(Error del hilo de trabajo:, err);
  });
 
  worker.on('exit', (code) => {
    if (code !== 0) {
      console.error(El hilo de trabajo salió de forma anormal, código de salida:: ${code}`);
    }
  });
} else {
  // Código del hilo de trabajo
  require('./worker.js');
}

Código del hilo de trabajo (worker.js):

Ejemplo

const { parentPort, workerData } = require('worker_threads');

console.log(Este es el hilo de trabajo);
console.log(Mensaje recibido del hilo principal:, workerData.message);

// Simular algo de trabajo
setTimeout(() => {
  // Enviar un mensaje al hilo principal
  parentPort.postMessage(¡Trabajo completado!);
}, 2000);

Uso avanzado

Transferir datos complejos

Ejemplo

// Hilo principal
const worker = new Worker('./worker.js', {
  workerData: {
    array: new Uint8Array([1, 2, 3, 4]),
    object: { key: 'value' }
  }
});

// Hilo de trabajo
console.log(workerData.array);  // Uint8Array [ 1, 2, 3, 4 ]
console.log(workerData.object); // { key: 'value' }

Memoria compartida (SharedArrayBuffer)

Ejemplo

// Hilo principal
const sharedBuffer = new SharedArrayBuffer(16);
const arr = new Uint8Array(sharedBuffer);
arr[0] = 1;

const worker = new Worker('./worker.js', {
  workerData: { sharedBuffer }
});

// Hilo de trabajo
const { sharedBuffer } = workerData;
const arr = new Uint8Array(sharedBuffer);
console.log(arr[0]); // 1

Mejores prácticas

  1. Uso razonable: no cree un hilo para cada tarea pequeña; la creación de hilos tiene sobrecarga
  2. Manejo de errores: escuche siempre los eventos 'error' y 'exit' del hilo de trabajo
  3. Limpieza de recursos: asegúrese de que el hilo de trabajo salga correctamente después de completar la tarea
  4. Optimización de la comunicación: minimice la cantidad de datos de comunicación entre hilos
  5. Afinidad de CPU: para hilos de larga duración, considere configurar la afinidad de CPU

Consideraciones de rendimiento

  1. Grupo de hilos: para tareas cortas frecuentes, considere usar el patrón de grupo de hilos
  2. Equilibrio de carga: distribuya uniformemente los hilos de trabajo en sistemas multinúcleo
  3. Uso de memoria: cada hilo de trabajo tiene su propia instancia de V8 y espacio de memoria

Preguntas frecuentes

¿Cuándo se debe usar worker_threads?

  • Cálculo intensivo en CPU
  • Necesidad de procesar múltiples tareas en paralelo
  • Necesidad de aprovechar CPU multinúcleo

¿Cuál es la diferencia entre worker_threads y el módulo cluster?

  • clusterCrea múltiples procesos de Node.js
  • worker_threadsCrea hilos que comparten el mismo proceso

¿Cómo depurar los hilos de trabajo?

Use--inspecty--inspect-brkel indicador y asigne un puerto de depuración diferente a cada hilo de trabajo.

Ejemplo

node --inspect=9229 main.js

Resumen

de Node.jsworker_threadsEl módulo aporta a JavaScript una verdadera capacidad de subprocesos múltiples, permitiendo a los desarrolladores aprovechar mejor el rendimiento de las CPU multinúcleo modernas. Mediante el uso razonable de los hilos de trabajo, se puede mejorar significativamente el rendimiento de las aplicaciones intensivas en CPU, manteniendo al mismo tiempo las ventajas de E/S no bloqueante de Node.js.

Java FileMódulos integrados de Node.js

Otras extensiones