2011-03-01 17 views
28

¿Alguien sabe cuáles son los modelos de memoria y de subprocesamiento en nodejs?Modelos de concurrencia en nodejs

En particular, ¿es ii++ atómico? ¿Se comporta como si ii fuera volatile en Java 1.5, en Java 1.4, en C, o en absoluto?

+2

Para todos los cuidados, node.js tiene un solo hilo. – Raynos

+2

@Raynos: No exactamente. Javascript se ejecuta en un solo subproceso, pero el bloqueo de IO se realiza en un grupo de subprocesos independiente. "Por supuesto, en el back-end, hay hilos y procesos para el acceso a DB y la ejecución del proceso". Cita: http://blog.mixu.net/2011/02/01/understanding-the-node-js-event-loop/ –

+1

Corrección: para todos ** usted ** care node.js tiene un solo hilo. –

Respuesta

37

Es útil entender cómo interactúan el nodo y el V8. El nodo maneja la espera de E/S o temporizadores del sistema operativo. Cuando el nodo se despierta de E/S o un temporizador, generalmente tiene algunas devoluciones de llamada de JavaScript para invocar. Cuando el nodo ejecuta estas devoluciones de llamada, el control pasa a V8 hasta que V8 regrese al nodo.

Por lo tanto, si lo hace var ii = 1; ii++;, nunca encontrará que ii es algo distinto de 2. Todo JavaScript se ejecuta hasta su finalización, y luego el control se transfiere al nodo. Si hace doSomething(); doSomething();, siempre se ejecutará doSomething dos veces, y no volverá al bucle de eventos del nodo hasta que vuelva la segunda invocación de doSomething. Esto significa que puede bloquear completamente nodo de un simple error como este:

for (var i=0 ; i >= 0 ; i++) {} 

No mater cuántos de E/S devoluciones de llamada que se haya registrado, temporizadores programarse para que suene, o tomas espera de ser leído. Hasta que V8 regrese de ese bucle infinito, el nodo ya no funciona.

Esto es parte de lo que hace que la programación en el nodo sea tan agradable. Usted nunca tiene que preocuparse por el bloqueo. No hay condiciones de carrera o secciones críticas. Solo hay un hilo donde se ejecuta el código JavaScript.

+2

Tuve un momento estúpido y por un segundo no me di cuenta de por qué era un ciclo infinito. Para alguien lento como yo, recuerde que la segunda condición en el ciclo for es la condición para _continuación_, no terminación. Es decir. el estándar para el ciclo que termina es "for (var i = 0; i <0; i ++) {}" – everybody

+3

¿es realmente infinito? ¿No me enrollaré en algún punto y me volveré negativo? – stu

+3

Prueba esto: '9007199254740992 + 1' – maletor

12

Solo hay un hilo (el bucle de evento) y su código nunca se interrumpe a menos que realice una acción asincrónica como I/O. No puede hacer ninguna ejecución paralela de código. Por lo tanto, ii ++ es atómico.

+0

Hubiera sido agradable si se dirigió al área gris. Por ejemplo, ¿qué pasa con esto: dosomething(); doanotherthing(); ??? –

+0

@Michael No hay área gris. doanotherthing() siempre se ejecuta después de dosomething() sin la posibilidad de cambiar el control en el medio (con la excepción de que dosomething() genera una excepción). Ver también la respuesta de @Matt, que explica esto con más detalle. – alienhard

+0

El área gris es que dos llamadas a funciones son secuenciales, a menos que lo hagan, y eso no siempre es claro cuando usa código de terceros. –

4

Un buen artículo que explica lo que es, y no es, asincrónico en node.js es Understanding the node.js Event Loop. Si puede comprender que podrá identificar dónde su aplicación tiene un comportamiento asincrónico y dónde no. Al entender esto, puede escribir código secuencial explícitamente cuando lo necesite. EventEmitters son la clave.

Singlethreadedness suena en desacuerdo con la idea de que node.js es de alto rendimiento y escalable, así que eche un vistazo a este article from Yahoo on Multicore.