Introducción a la memoria compartida en JavaScript
La memoria compartida es una función avanzada de JavaScript, que los subprocesos (partes de un proceso ejecutados simultáneamente) pueden aprovechar. Compartir la memoria significa no tener el problema de pasar datos actualizados entre subprocesos y todos los subprocesos pueden acceder y actualizar los mismos datos en la memoria compartida.
¿No suena adorable? Bueno, casi. En esta publicación, veremos cómo usar la memoria compartida en JavaScript y cómo decidir si esto es lo que realmente desea hacer.
Ventajas y desventajas de la memoria compartida
Usamos trabajadores web para crear hilos en JavaScript . Web Workers API nos permite crear subprocesos de trabajo que se pueden utilizar para ejecutar código en segundo plano, de modo que el hilo principal sea libre de continuar su ejecución, posiblemente procesando eventos de UI, asegurando que no se congele la UI.
Los subprocesos de trabajo se ejecutan simultáneamente con el subproceso principal y entre ellos . Tal ejecución simultánea de diferentes partes de una tarea ahorra tiempo. Terminas más rápido, pero también tiene su propio conjunto de problemas.
Asegurarse de que cada hilo obtenga los recursos necesarios y se comunique entre ellos de manera oportuna es una tarea en sí misma, en la que un error puede resultar en un resultado sorprendente. O bien, si un hilo está cambiando datos y otro lo está leyendo al mismo tiempo, ¿qué crees que verá el otro hilo? ¿Los datos actualizados o antiguos?
Sin embargo, los trabajadores de la web no son tan fáciles de arruinar. Durante su comunicación mediante el uso de mensajes, los datos que se envían entre sí no son originales sino una copia, lo que significa que no comparten los mismos datos. Pasan copias de datos entre sí cuando es necesario.
Sin embargo, compartir es importante, y es posible que también sea necesario que varios hilos vean los mismos datos al mismo tiempo y los modifiquen. Entonces, prohibir compartir es un gran no-no . Aquí es donde el objeto SharedArrayBuffer
entra en la imagen. Nos permitirá compartir datos binarios entre múltiples hilos .
El objeto SharedArrayBuffer
En lugar de pasar las copias de datos entre subprocesos, pasamos copias del objeto SharedArrayBuffer
. Un objeto SharedArrayBuffer
apunta a la memoria donde se guardan los datos .
Por lo tanto, incluso cuando las copias de SharedArrayBuffer
se pasan entre subprocesos, todas seguirán apuntando a la misma memoria donde se guardan los datos originales. Los hilos, por lo tanto, pueden ver y actualizar los datos en esa misma memoria .
Para ver cómo funciona un trabajador web sin utilizar la memoria compartida, creamos un hilo de trabajo y le pasamos algunos datos .
El archivo index.html
contiene el script principal dentro de etiqueta, como puedes ver a continuación:
const w = new Worker ('worker.js'); var n = 9; w.postMessage (n);
El archivo worker.js
lleva el script de trabajador :
onmessage = (e) => {console.group ('[worker]'); console.log ('Datos recibidos del hilo principal:% i', e.data); console.groupEnd (); }
Usando el código anterior, obtenemos el siguiente resultado en la consola :
[trabajador] Datos recibidos del hilo principal: 9
Puede leer mi publicación antes mencionada en trabajadores de la web para obtener la explicación completa del código de los fragmentos anteriores.
Por ahora, tenga en cuenta que los datos se envían entre hilos usando el método postMessage()
. El manejador de eventos del message
recibe los datos en el otro lado, como el valor de la propiedad de data
del evento.
Ahora, si cambiamos los datos, ¿aparecerá actualizado en el extremo receptor? Veamos:
const w = new Worker ('worker.js'); var n = 9; w.postMessage (n); n = 1;
Como era de esperar, los datos no se han actualizado :
[trabajador] Datos recibidos del hilo principal: 9
¿Por qué sería, de todos modos? Es solo un clon enviado al trabajador desde el script principal .
Trabajadores web con memoria compartida
Ahora, usaremos el objeto SharedArrayBuffer
en el mismo ejemplo. Podemos crear una nueva instancia de SharedArrayBuffer
utilizando la new
palabra clave . El constructor toma un parámetro; un valor de longitud en bytes, que especifica el tamaño del búfer.
const w = new Worker ('worker.js'); buff = new SharedArrayBuffer (1); var arr = new Int8Array (buff); / * configuración de datos * / arr [0] = 9; / * enviando el buffer (copy) al worker * / w.postMessage (buff);
Tenga en cuenta que un objeto SharedArrayBuffer
representa solo un área de memoria compartida . Para ver y cambiar los datos binarios, necesitamos usar una estructura de datos apropiada (un TypedArray
o un objeto DataView
).
En el archivo index.html
anterior, se crea un nuevo SharedArrayBuffer
, con solo un byte de longitud. A continuación, se Int8Array
una nueva Int8Array
, que es un tipo de objetos TypedArray
, para establecer los datos en "9" en el espacio de bytes provisto .
onmessage = (e) => {var arr = nuevo Int8Array (e.data); console.group ('[worker]'); console.log ('Datos recibidos del hilo principal:% i', arr [0]); console.groupEnd (); }
Int8Array
también se usa en el trabajador para ver los datos en el búfer .
El valor esperado aparece en la consola desde el hilo de trabajo, que es exactamente lo que queríamos:
[trabajador] Datos recibidos del hilo principal: 9
Ahora, actualicemos los datos en el hilo principal para ver si el cambio se refleja en el trabajador.
const w = new Worker ('worker.js'), buff = new SharedArrayBuffer (1); var arr = new Int8Array (buff); / * configuración de datos * / arr [0] = 9; / * enviando el buffer (copy) al worker * / w.postMessage (buff); / * cambiando los datos * / arr [0] = 1;
Y, como puede ver a continuación, ¡la actualización se refleja dentro del trabajador !
[trabajador] Datos recibidos del hilo principal: 1
Pero, el código también debe funcionar al revés : cuando el valor en el trabajador cambia al principio, también debe actualizarse cuando se imprima desde el hilo principal.
En este caso, nuestro código se ve así:
onmessage = (e) => {var arr = nuevo Int8Array (e.data); console.group ('[worker]'); console.log ('Datos recibidos del hilo principal:% i', arr [0]); console.groupEnd (); / * cambiando los datos * / arr [0] = 7; / * publicación en el hilo principal * / postMessage (''); }
Los datos se cambian en el trabajador y se envía un mensaje vacío al hilo principal que indica que los datos en el búfer se han cambiado y que está listo para la salida del hilo principal.
const w = new Worker ('worker.js'), buff = new SharedArrayBuffer (1); var arr = new Int8Array (buff); / * configuración de datos * / arr [0] = 9; / * enviando el buffer (copy) al worker * / w.postMessage (buff); / * cambiando los datos * / arr [0] = 1; / * imprime los datos después de que el trabajador lo haya cambiado * / w.onmessage = (e) => {console.group ('[main]'); console.log ('Datos actualizados recibidos del hilo de trabajo:% i', arr [0]); console.groupEnd (); }
¡Y esto también funciona! Los datos en el buffer son los mismos que los datos dentro del trabajador.
[trabajador] Datos recibidos del hilo principal: 1 [principal] Datos actualizados recibidos del hilo de trabajo: 7
El valor aparece actualizado en ambos casos ; tanto el hilo principal como el hilo de trabajo están viendo y cambiando los mismos datos.
Ultimas palabras
Como mencioné anteriormente, el uso de memoria compartida en JavaScript no deja de tener inconvenientes . Depende de los desarrolladores asegurarse de que la secuencia de ejecución ocurra como se predijo y que no haya dos hilos compitiendo para obtener los mismos datos porque nadie sabe quién se llevará el trofeo.
Si le interesa más la memoria compartida, eche un vistazo a la documentación del objeto Atomics
. El objeto Atomics puede ayudarlo con algunas de las dificultades, al reducir la naturaleza impredecible de la lectura / escritura de la memoria compartida.
Construya páginas de aterrizaje de alta calidad con Qards [Plugin de WordPress]
¿Le resulta difícil construir sus páginas web exactamente de la manera que desea que se vean? ¿El proceso de creación tarda más de lo que te gustaría, incluso con la ayuda de un tema de WordPress? Entonces, es posible que desee probar Qards.Qards es un plugin de WordPress, producido por Designmodo, que le permite editar páginas existentes o producir páginas nuevas de la manera que usted lo desee. Hace us
Desarrolladores web: 10 mejores canales de podcast que necesita para suscribirse a
El desarrollo web es una industria rápida en constante cambio. Para mantenerse al tanto, debe mantenerse constantemente informado con lo último y mejor, y una de las mejores maneras de hacerlo es suscribirse a un podcast . Podcast o Podcasting es un medio fascinante para obtener información y noticias, especialmente en momentos como cuando vas a la oficina o tienes una carrera en el gimnasio.Al