node.js maneja el bloqueo de la operación de E / S

0

Quiero comprender el funcionamiento interno de node.js, estoy incluyendo intencionalmente la tarea de cálculo (para bucle). Pero veo que todavía está bloqueando el hilo principal.

Aqui esta mi guion

console.log("start");

for (let i = 0; i < 10; i++) {
    console.log(i)
}

console.log("end")

Y el o / p es: empezar

1

2

3

....

10

fin

Pero de acuerdo con la arquitectura de node.js, ¿las tareas de alto cálculo no deberían ser ejecutadas por diferentes subprocesos seleccionados del grupo de subprocesos y el bucle de eventos continúe ejecutando la tarea sin bloqueo? ingrese la descripción de la imagen aquí

Estoy haciendo referencia a la arquitectura interna de node.js usando este enlace, ingrese la descripción del enlace aquí

¿Alguien puede explicar la arquitectura y el comportamiento del guión?

1
  • 1
    ¿Por qué crees que está bloqueando el hilo principal? Solo hay un hilo y está escribiendo código sincrónico.
    madflow
    13 de oct a las 16:07
2

De forma predeterminada, nodejs usa solo UN hilo para ejecutar su Javascript. Eso significa que (a menos que involucre WorkerThreads, que son esencialmente una máquina virtual completamente separada), solo una parte de Javascript se ejecuta a la vez. Nodejs no "detecta" algún fragmento de Javascript de larga ejecución y lo mueve a otro hilo. No tiene características como esa en absoluto. Si tiene alguna pieza de Javascript síncrono de larga ejecución, bloqueará el bucle de eventos y bloqueará todos los demás Javascript y todos los demás procesos de eventos.

Internamente a su implementación, nodejs tiene un grupo de subprocesos que utiliza para ciertos tipos de código nativo (implementaciones internas de E / S de archivos y operaciones criptográficas). Eso solo admite la implementación de implementaciones asíncronas para operaciones de E / S de archivos y criptografía; no paraleliza la ejecución de Javascript.

Entonces, muestra su guión:

console.log("start");

for (let i = 0; i < 10; i++) {
    console.log(i)
}

console.log("end")

Es completamente sincrónico y se ejecuta secuencialmente y bloquea el resto de Javascript para que no se ejecuten mientras se está ejecutando porque está utilizando un hilo para ejecutar Javascript mientras se está ejecutando.

Nodejs obtiene su excelente escalabilidad de su modelo de E / S asincrónico que no tiene que usar un hilo separado para tener muchas operaciones asincrónicas en vuelo al mismo tiempo. Pero tenga en cuenta que todas estas operaciones de E / S asincrónicas tienen código nativo detrás de ellas (algunas de las cuales pueden usar subprocesos en sus implementaciones de código nativo).

Pero, si tiene operaciones de Javascript síncronas de ejecución prolongada (como por ejemplo, algo como análisis de imágenes escrito en Javascript), entonces esas normalmente deben moverse fuera del hilo del bucle de eventos principal, ya sea desviándolas a WorkerThreads oa otros procesos oa un implementación de código nativo que puede usar subprocesos del sistema operativo.

But according to node.js architecture shouldn't high computation tasks be executed by different thread picked from thread pool and event loop continue executing non-blocking task?

No, no es así como funciona nodejs y no es una interpretación correcta del diagrama que muestra. El grupo de subprocesos NO se utiliza para ejecutar su Javascript. Se utiliza para la implementación interna de algunas API, como E / S de archivos y algunas operaciones de cifrado. No se utiliza para ejecutar su Javascript. Solo hay un hilo principal para ejecutar su Javascript (a menos que ejecute específicamente su código en un WorkerThread).

I want to understand internal working of node.js, I am intentionally including computation task ( for loop). But I see it is still blocking main thread.

Sí, un forbucle (que no contiene una awaitdeclaración que esté esperando una promesa) ocupará por completo el único hilo de Javascript y bloqueará el bucle de eventos para que no procese otros eventos mientras el forbucle se está ejecutando.

0

JS ejecuta su código Synchronouse. hay pocas cosas que obtienen "Asynchronouse" como setIntervalo setTimoutpor ejemplo. Pero eso en realidad no es del todo cierto. Asynchronouse significa que las cosas se hacen en paralelo, lo que no es cierto. Échale un vistazo setTimeout. Al ejecutarlo, agrega la función a la cola de tareas, luego el bucle de eventos la toma de la cola, la coloca en la pila y la ejecuta, syncrhonouse. Si desea ejecutar algo realmente paralelo, debería considerar usar un hilo de trabajo

0

No hay absolutamente ningún hilo en JS (a menos que utilice explícitamente hilos de trabajo). Javascript utiliza multitarea cooperativa, lo que significa que una función siempre se completará antes de que comience la siguiente. La única otra forma de devolver el control al planificador es separar una tarea en otra función que se llama asincrónicamente. Entonces, en su ejemplo, por ejemplo, podría hacer:

console.log("start");
setTimeout(() => { 
  for (let i = 0; i < 10; i++) {
    console.log(i)
  }}, 0);
console.log("end")

y obtendrías:

start
end
1
2
..
9

Esto también responde a su pregunta sobre cálculos pesados: a menos que use los subprocesos de trabajo relativamente nuevos , no puede ejecutar cálculos pesados ​​en node.js "en segundo plano" sin el uso de código nativo.

Entonces, si realmente tiene cargas pesadas, tiene tres opciones:

  • hilos de trabajo,
  • código nativo que es multiproceso, por ejemplo, escrito en C / C ++, o
  • dividiendo su cálculo en pequeñas partes, cada una de las cuales devuelve el control al programador cuando termina (por ejemplo, usando map / reduce).
4
  • Hola Christian, De acuerdo con el diagrama y la explicación del diagrama, el bucle de eventos comprueba si una tarea determinada se está bloqueando. En caso afirmativo, selecciona un nuevo hilo del grupo de hilos y esto ejecuta la tarea y devuelve la respuesta / rendimiento al bucle de eventos 13 de oct a las 16:16
  • Varias cosas están mal en esta respuesta. Absolutamente hay subprocesos internos a la implementación de nodejs que se utilizan para cosas como E / S de archivos asíncronos y operaciones criptográficas asíncronas. De forma predeterminada, hay un hilo para ejecutar su Javascript hasta que se involucre en WorkerThreads. 13 de oct a las 16:16
  • Entonces, ¿el bucle for se está ejecutando en un hilo diferente de acuerdo con mi script? 13 de oct a las 16:17
  • @karthik_personal no, nada se está ejecutando en un hilo diferente, todo se está ejecutando en 1 hilo. si desea un subproceso, use subprocesos de trabajo
    Ifaruki
    13 de oct a las 16:22