2008-09-02 12 views
192

¿Es una decisión de diseño deliberada o un problema con nuestros navegadores actuales que se rectificará en las próximas versiones?¿Por qué JavaScript no es compatible con multiprocesamiento?

+84

Hola, compañero de Google. Puede notar que todo aquí parece estar bastante anticuado (tenga en cuenta que esta pregunta se hizo hace más de 5 años). Desde que se solicitó, los navegadores web han adquirido algunas capacidades que, hasta donde puedo decir, son más o menos multithreading. Eche un vistazo a Web Workers: http://msdn.microsoft.com/en-us/hh549259.aspx – ArtOfWarfare

+2

Vea también las respuestas a [JavaScript and Threads] (http://stackoverflow.com/questions/30036/javascript -and-threads # 30197) pregunta para obtener información acerca de los trabajadores de la web/hilos de trabajo. –

Respuesta

139

JavaScript no es compatible con multi-threading porque el intérprete de JavaScript en el navegador es un hilo único (AFAIK). Incluso Google Chrome no permitirá que el JavaScript de una sola página web se ejecute al mismo tiempo porque esto causaría problemas de simultaneidad masiva en las páginas web existentes. Todo lo que hace Chrome es separar los componentes múltiples (diferentes pestañas, complementos, etcétera) en procesos separados, pero no puedo imaginar una sola página que tenga más de un hilo de JavaScript.

Sin embargo, puede utilizar, como se sugirió, setTimeout para permitir algún tipo de programación y concurrencia "falsa". Esto hace que el navegador recupere el control del hilo de representación e inicie el código JavaScript suministrado al setTimeout después de la cantidad de milisegundos especificada. Esto es muy útil si desea permitir que la ventana gráfica (lo que ve) se actualice mientras realiza operaciones en ella. Solo haciendo un bucle, p. Ej. las coordenadas y la actualización de un elemento en consecuencia le permitirán ver las posiciones inicial y final, y nada entre ellas.

Utilizamos una biblioteca de abstracción en JavaScript que nos permite crear procesos e hilos que son todos gestionados por el mismo intérprete de JavaScript. Esto nos permite ejecutar acciones de la siguiente manera:

  • Proceso A, Tema 1
  • Proceso A, Tema 2
  • Proceso B, Tema 1
  • Proceso A, Tema 3
  • Proceso A, Tema 4
  • Proceso B, hilo 2
  • Pausa Proceso A
  • Proceso B, hilo 3
  • Proceso B, Hilo 4
  • Proceso B, Hilo 5
  • Start Proceso A
  • Proceso A, Tema 5

Esto permite algún tipo de programación y falsificaciones paralelismo, arranque y parada de hilos, etcétera, pero no será cierto multihilo.No creo que alguna vez se implemente en el idioma en sí, ya que el multi-threading verdadero solo es útil si el navegador puede ejecutar una sola página de subprocesos múltiples (o incluso más de un núcleo), y las dificultades allí son mucho más grandes que las posibilidades adicionales.

Por el futuro de JavaScript, mira esto: http://developer.mozilla.org/presentations/xtech2006/javascript/

+56

Creo * nunca implementado * es una visión demasiado estrecha. Garantizo que las aplicaciones web finalmente podrán ser multiproceso (es lógico, ya que las aplicaciones web se vuelven más dominantes, y el hardware se vuelve más paralelo), y como yo lo veo, dado que JavaScript es el lenguaje de facto del desarrollo web, eventualmente tendrá que admitir el subprocesamiento múltiple o ser reemplazado por algo que sí lo haga. – devios1

+6

Nunca es probablemente una afirmación demasiado audaz :) pero sigo pensando que las ventajas de un javascript multiproceso verdadero no son factibles en un futuro previsible;) –

+20

trabajadores web == multihebra –

0

Por lo que he oído, Google Chrome tendrá Javascript multiproceso, por lo que es un problema de "implementaciones actuales".

0

Según this article ya es posible implementar el enhebrado de JavaScript.

+2

Desafortunadamente, esta técnica no proporciona el enhebrado verdadero, sino que simplemente divide las tareas en trozos pequeños y les permite turnarse en el hilo de la interfaz de usuario. Es útil, pero sus núcleos adicionales no podrán ayudar en absoluto. –

6

¿Quiere decir por qué el lenguaje no admite multihebras o por qué los motores de JavaScript en los navegadores no admiten multihilo?

La respuesta a la primera pregunta es que JavaScript en el navegador debe ejecutarse en un entorno limitado y en una máquina/sistema operativo independiente, para agregar soporte de subprocesos múltiples complicaría el lenguaje y vincularía el lenguaje demasiado cerca del OS.

0

Son las implementaciones que no admiten multithreading. Actualmente, Google Gears proporciona una forma de utilizar algún tipo de concurrencia mediante la ejecución de procesos externos, pero eso es todo.

El nuevo navegador que se supone que Google lanzará hoy (Google Chrome) ejecuta algún código en paralelo separándolo en proceso.

El lenguaje central, por supuesto, puede tener el mismo soporte que, por ejemplo, Java, pero el soporte para algo así como la concurrencia de Erlang no está cerca del horizonte.

11

No conozco los motivos de esta decisión, pero sé que puede simular algunos de los beneficios de la programación de subprocesos múltiples utilizando setTimeout. Puedes dar la ilusión de múltiples procesos haciendo cosas al mismo tiempo, aunque en realidad, todo sucede en un hilo.

acabamos de su función de hacer un poco de trabajo, y luego llamar algo así como:

setTimeout(function() { 
    ... do the rest of the work... 
}, 0); 

y cualquier otra cosas que hay que hacer (como actualizaciones de la interfaz de usuario, imágenes animadas, etc.) que va a pasar cuando lleguen una oportunidad.

+0

La mayoría de los casos quisiera usar un 'loop' dentro del' setTimeout' pero aparentemente eso no funciona. ¿Has hecho algo así o tienes un truco? un ejemplo sería para una matriz de 1000 elementos, espero usar dos bucles for dentro de dos llamadas 'setTimeout' de modo que el primer bucle pase e imprima el elemento' 0..499', el segundo pase e imprima el elemento '500 .. 999'. – benjaminz

+0

Por lo general, la técnica es guardar el estado y continuar. Por ejemplo, digamos que desea imprimir 0 a 1000, puede imprimir de 0 a 499 y luego hacer el truco de setTimeout con el argumento 500. El código interno sabrá tomar el argumento (500) y comenzar el ciclo desde allí. – Eyal

20

Tradicionalmente, JS estaba destinado para piezas cortas y de código de ejecución rápida. Si tenía grandes cálculos en curso, lo hizo en un servidor: la idea de una aplicación JS + HTML que se ejecutara en su navegador durante largos períodos de tiempo haciendo cosas no triviales era absurda.

Por supuesto, ahora tenemos eso. Sin embargo, los navegadores tardarán un poco en ponerse al día: la mayoría de ellos se han diseñado en torno a un modelo de subproceso único, y cambiar eso no es fácil. Google Gears minimiza muchos problemas potenciales al requerir que la ejecución en segundo plano esté aislada, sin cambiar el DOM (ya que no es seguro para subprocesos), sin acceder a objetos creados por el hilo principal (ídem). Aunque restrictivo, este será probablemente el diseño más práctico para el futuro cercano, tanto porque simplifica el diseño del navegador, como porque reduce el riesgo de permitir que los codificadores JS inexpertos entren en problemas con los hilos ...

@marcio :

¿Por qué es una razón para no implementar multi-threading en Javascript? Los programadores pueden hacer lo que quieran con las herramientas que tienen.

Así pues, no hay que darles herramientas que son tan fáciles de mal uso que cualquier otro sitio web i abrir termina chocando mi navegador. Una implementación ingenua de esto te llevaría directo al territorio que causó muchos dolores de cabeza a MS durante el desarrollo de IE7: los autores de complementos jugaron rápido y suelto con el modelo de subprocesamiento, resultando en errores ocultos que se hicieron evidentes cuando los ciclos de vida de los objetos cambiaban en el hilo principal . MALO. Si está escribiendo complementos ActiveX de subprocesos múltiples para IE, supongo que viene con el territorio; no significa que deba ir más allá de eso.

+3

"reduce el riesgo involucrado > al permitir codificadores JS inexpertos > perder el tiempo con los hilos" ¿Por qué es una razón para no implementar multi-threading en Javascript? Los programadores pueden hacer lo que quieran con las herramientas que tienen. Si es bueno o malo, es su problema. Con el modelo de proceso de Google Chrome, no puede afectar a otras aplicaciones. :) –

+2

@ Shog9 - "No demos herramientas [a los programadores] tan fáciles de usar que cada otro sitio web que abro termine bloqueando mi navegador". - ¿Qué? Según esa misma lógica, ningún lenguaje debería tener multihilo, porque si ofrecieran que cada otro programa que intentaste abrir se bloqueara. Excepto que no funciona de esa manera. El enhebrado existe en la mayoría de los lenguajes y la mayoría de los programadores principiantes no lo tocan, y la mayoría de los que no lo ponen en producción, y esas aplicaciones que nunca se vuelven populares o se usan ampliamente. – ArtOfWarfare

5

Como dijo matt b, la pregunta no es muy clara. Suponiendo que está preguntando por el soporte de subprocesos múltiples en el idioma: porque no es necesario para el 99.999% de las aplicaciones que se ejecutan actualmente en el navegador. Si realmente lo necesita, hay soluciones (como usar window.setTimeout).

En general, el multihilo es muy, muy, muy, muy, muy, muy duro (¿dije que es difícil?) Para hacerlo bien, a menos que impongas restricciones adicionales (como usar solo datos inmutables).

0

Sin apoyo en el idioma adecuado para la sincronización de hilo, que ni siquiera tiene sentido para las nuevas implementaciones para probar. Las aplicaciones JS complejas existentes (por ejemplo, cualquier cosa que utilice ExtJS) probablemente colapsarían inesperadamente, pero sin una palabra clave synchronized o algo similar, también sería muy difícil o incluso imposible escribir programas nuevos que se comporten correctamente.

18

JavaScript multi-threading (con algunas limitaciones) está aquí. Google implementó trabajadores para Gears y los trabajadores se incluyen con HTML5. La mayoría de los navegadores ya han agregado soporte para esta función.

Se garantiza la seguridad de subprocesos de datos porque todos los datos comunicados al/del trabajador se serializan/copian.

Para obtener más información, lea:

http://www.whatwg.org/specs/web-workers/current-work/

http://ejohn.org/blog/web-workers/

+4

Pero, ¿no es más un enfoque de procesos múltiples en lugar de multihilo? Se sabe que los subprocesos funcionan dentro de un solo montón. – beefeather

+1

@beefeather, eso es cierto. Es más un enfoque de proceso. –

3

Intel ha estado haciendo algunas investigaciones de código abierto en múltiples hilos en Javascript, que fue exhibido recientemente en la GDC 2012. Aquí es el enlace para el video. El grupo de investigación utilizó OpenCL que se centra principalmente en conjuntos de chips Intel y SO Windows. El proyecto es Rivertrail nombre en código y el código está disponible en GitHub

Algunos enlaces más útiles:

Building a Computing Highway for Web Applications

9

Multithread.js envuelve Web Workers y permite una fácil multihilo en JS. Funciona en todos los navegadores nuevos, incluido iOS Safari. :)

-2

Multi-threading con javascript es claramente posible usando webworkers bring by HTML5.

diferencia principal entre webworkers y un entorno de múltiples hilos estándar es de recursos de memoria no se comparten con el hilo principal, una referencia a un objeto no es visible desde un hilo a otro. Los hilos se comunican mediante el intercambio de mensajes, por lo tanto, es posible implementar un algoritmo de llamada de sincronización y método concurrente siguiendo un patrón de diseño impulsado por eventos.

Muchos marcos existe lo que permite estructurar programación entre hilos, entre ellos OODK-JS, un marco de programación orientada a objetos js apoyo a la programación concurrente https://github.com/GOMServices/oodk-js-oop-for-js

+4

Compartir memoria es la definición exacta de un subproceso que se opone a un proceso separado (por ejemplo, fork() vs exec()). Los hilos pueden compartir objetos, los procesos deben usar IPC. Los trabajadores de la web no son multitarea. – felixfbecker

0

Sin embargo, puede utilizar la función eval para llevar a la concurrencia, en cierta medida

/* content of the threads to be run */ 
var threads = [ 
     [ 
      "document.write('Foo <br/>');", 
      "document.write('Foo <br/>');", 
      "document.write('Foo <br/>');", 
      "document.write('Foo <br/>');", 
      "document.write('Foo <br/>');", 
      "document.write('Foo <br/>');", 
      "document.write('Foo <br/>');", 
      "document.write('Foo <br/>');", 
      "document.write('Foo <br/>');", 
      "document.write('Foo <br/>');" 
     ], 
     [ 
      "document.write('Bar <br/>');", 
      "document.write('Bar <br/>');", 
      "document.write('Bar <br/>');", 
      "document.write('Bar <br/>');", 
      "document.write('Bar <br/>');", 
      "document.write('Bar <br/>');", 
      "document.write('Bar <br/>');", 
      "document.write('Bar <br/>');", 
      "document.write('Bar <br/>');" 
     ] 
    ]; 

window.onload = function() { 
    var lines = 0, quantum = 3, max = 0; 

    /* get the longer thread length */ 
    for(var i=0; i<threads.length; i++) { 
     if(max < threads[i].length) { 
      max = threads[i].length; 
     } 
    } 

    /* execute them */ 
    while(lines < max) { 
     for(var i=0; i<threads.length; i++) { 
      for(var j = lines; j < threads[i].length && j < (lines + quantum); j++) { 
       eval(threads[i][j]); 
      } 
     } 
     lines += quantum; 
    } 
} 
Cuestiones relacionadas