hideout-lastation.com
Paradis Pour Les Concepteurs Et Les Développeurs


Introduction à la mémoire partagée en JavaScript

La mémoire partagée est une fonctionnalité avancée de JavaScript, que les threads (parties d'un processus exécutées simultanément) peuvent exploiter. Partager la mémoire signifie ne pas avoir de mal à transmettre des données mises à jour entre les threads et tous les threads peuvent accéder et mettre à jour les mêmes données dans la mémoire partagée.

Cela ne semble-t-il pas charmant? Eh bien, presque. Dans cet article, nous verrons comment utiliser la mémoire partagée dans JavaScript et comment décider si c'est ce que vous voulez vraiment faire.

Avantages et inconvénients de la mémoire partagée

Nous utilisons des web workers pour créer des threads en JavaScript . L'API Web Workers permet de créer des threads de travail qui peuvent être utilisés pour exécuter du code en arrière-plan afin que le thread principal puisse continuer son exécution, traitant éventuellement des événements de l'interface utilisateur, sans aucune interruption de l'interface utilisateur.

Les threads de travail s'exécutent simultanément avec le thread principal et entre eux . Une telle exécution simultanée de différentes parties d'une tâche permet de gagner du temps. Vous finissez plus vite, mais il a aussi ses propres problèmes.

S'assurer que chaque thread obtient les ressources nécessaires et communique les uns avec les autres en temps opportun est une tâche en soi, où une mésaventure peut aboutir à un résultat surprenant. Ou, si un thread change des données et qu'un autre le lit en même temps, que pensez-vous que l'autre thread verra? Les mises à jour ou les anciennes données?

Cependant, les web workers ne sont pas si faciles à bousiller. Lors de leur communication via l'utilisation de messages, les données qu'ils se transmettent ne sont pas originales mais une copie, ce qui signifie qu'ils ne partagent pas les mêmes données. Ils transmettent des copies de données les uns aux autres en cas de besoin.

Mais le partage est attentionné, et plusieurs threads peuvent aussi avoir besoin de regarder les mêmes données en même temps et de les changer. Donc, interdire le partage est un gros non-non . C'est là que l'objet SharedArrayBuffer entre dans l'image. Cela nous permettra de partager des données binaires entre plusieurs threads .

L'objet SharedArrayBuffer

Au lieu de passer les copies de données entre les threads, nous passons des copies de l'objet SharedArrayBuffer . Un objet SharedArrayBuffer pointe vers la mémoire où les données sont enregistrées .

Ainsi, même lorsque les copies de SharedArrayBuffer sont passées entre threads, elles pointent toutes vers la même mémoire où les données d'origine sont sauvegardées. Les threads peuvent ainsi visualiser et mettre à jour les données dans cette même mémoire .

Travailleurs Web sans mémoire partagée

Pour voir comment fonctionne un travailleur Web sans utiliser la mémoire partagée, nous créons un thread de travail et lui transmettons des données .

Le fichier index.html contient le script principal dans un tag, comme vous pouvez le voir ci-dessous:

 const w = new Worker ('worker.js'); var n = 9; w.postMessage (n); 

Le fichier worker.js porte le script worker :

 onmessage = (e) => {console.group ('[worker]'); console.log ('Données reçues du thread principal:% i', e.data); console.groupEnd (); } 

En utilisant le code ci-dessus, nous obtenons la sortie suivante dans la console :

 [worker] Données reçues du thread principal: 9 

Vous pouvez lire mon article mentionné ci-dessus sur les travailleurs Web pour l'explication complète du code des extraits ci-dessus.

Pour l'instant, gardez à l'esprit que les données sont envoyées entre les threads en utilisant la méthode postMessage() . Les données sont reçues de l'autre côté par le gestionnaire d'événements de message, en tant que valeur de la propriété de data de l'événement.

Maintenant, si nous changeons les données apparaîtront-elles mises à jour à la réception? Voyons voir:

 const w = new Worker ('worker.js'); var n = 9; w.postMessage (n); n = 1; 

Comme prévu, les données n'ont pas été mises à jour :

 [worker] Données reçues du thread principal: 9 

Pourquoi serait-ce, de toute façon? C'est juste un clone envoyé au travailleur à partir du script principal .

Travailleurs Web avec mémoire partagée

Maintenant, nous allons utiliser l'objet SharedArrayBuffer dans le même exemple. Nous pouvons créer une nouvelle instance de SharedArrayBuffer en utilisant le new mot-clé . Le constructeur prend un paramètre; une valeur de longueur en octets, en spécifiant la taille du tampon.

 const w = new Worker ('worker.js'); buff = new SharedArrayBuffer (1); var arr = new Int8Array (buff); / * réglage des données * / arr [0] = 9; / * envoi du tampon (copie) au worker * / w.postMessage (buff); 

Notez qu'un objet SharedArrayBuffer représente uniquement une zone de mémoire partagée . Pour voir et modifier les données binaires, nous devons utiliser une structure de données appropriée (un TypedArray ou un objet DataView ).

Dans le fichier index.html ci-dessus, un nouveau SharedArrayBuffer est créé, avec une longueur d'un octet seulement. Ensuite, un nouvel Int8Array, qui est un type d'objets TypedArray, est utilisé pour définir les données sur "9" dans l'espace d'octets fourni .

 onmessage = (e) => {var arr = nouveau Int8Array (e.data); console.group ('[worker]'); console.log ('Données reçues du thread principal:% i', arr [0]); console.groupEnd (); } 

Int8Array est également utilisé dans le worker pour visualiser les données dans le buffer .

La valeur attendue apparaît dans la console à partir du thread de travail, ce qui est exactement ce que nous voulions:

 [worker] Données reçues du thread principal: 9 

Maintenant, mettons à jour les données dans le thread principal pour voir si la modification est reflétée dans le travailleur.

 const w = new Travailleur ('worker.js'), buff = new SharedArrayBuffer (1); var arr = new Int8Array (buff); / * réglage des données * / arr [0] = 9; / * envoi du tampon (copie) au worker * / w.postMessage (buff); / * modification des données * / arr [0] = 1; 

Et, comme vous pouvez le voir ci-dessous, la mise à jour reflète dans le travailleur !

 [worker] Données reçues du thread principal: 1 

Mais le code doit également fonctionner dans l'autre sens : lorsque la valeur dans le worker change au début, elle doit également être mise à jour lorsqu'elle est imprimée à partir du thread principal.

Dans ce cas, notre code ressemble à ceci:

 onmessage = (e) => {var arr = nouveau Int8Array (e.data); console.group ('[worker]'); console.log ('Données reçues du thread principal:% i', arr [0]); console.groupEnd (); / * modification des données * / arr [0] = 7; / * publication dans le thread principal * / postMessage (''); } 

Les données sont modifiées dans le worker et un message vide est posté dans le thread principal pour signaler que les données dans le buffer ont été changées et sont prêtes pour le thread principal à sortir.

 const w = new Travailleur ('worker.js'), buff = new SharedArrayBuffer (1); var arr = new Int8Array (buff); / * réglage des données * / arr [0] = 9; / * envoi du tampon (copie) au worker * / w.postMessage (buff); / * modification des données * / arr [0] = 1; / * impression des données après que le worker l'a changé * / w.onmessage = (e) => {console.group ('[main]'); console.log ('Données mises à jour reçues du thread de travail:% i', arr [0]); console.groupEnd (); } 

Et, cela fonctionne aussi! Les données dans le tampon sont les mêmes que les données dans le worker.

 [worker] Données reçues du thread principal: 1 [main] Données mises à jour reçues du thread de travail: 7 

La valeur apparaît mise à jour dans les deux cas ; Les threads principal et de travail affichent et modifient les mêmes données.

Derniers mots

Comme je l'ai mentionné plus tôt, l'utilisation de la mémoire partagée en JavaScript n'est pas sans inconvénients . Il appartient aux développeurs de s'assurer que la séquence d'exécution se déroule comme prévu et qu'il n'y a pas deux threads qui courent pour obtenir les mêmes données car personne ne sait qui prendra le trophée.

Si vous souhaitez plus de mémoire partagée, consultez la documentation de l'objet Atomics . L' objet Atomics peut vous aider avec certaines des difficultés, en réduisant la nature imprévisible de la lecture / écriture de la mémoire partagée.

99 Tech Life Hacks vous devriez savoir

99 Tech Life Hacks vous devriez savoir

Un hack de vie est une stratégie, une technique, une astuce ou un raccourci qui peut rendre la vie plus facile - en accélérant l'efficacité, en augmentant la productivité et en minimisant parfois une source d'ennuis avec une astuce rapide. C'est aussi proche d'une définition de dictionnaire que vous pouvez obtenir.Aimez

(Conseils techniques et de conception)

Déplacement d'éléments dans la disposition de la grille CSS [Guide]

Déplacement d'éléments dans la disposition de la grille CSS [Guide]

L'utilisation du CSS Grid Layout Module dans la conception web devient de plus en plus faisable car de plus en plus de navigateurs commencent à le supporter . Lorsque vous créez des mises en page en remplissant des cellules de la grille, il peut arriver un moment, cependant, lorsque vous voulez réaliser des choses plus compliquées.Par

(Conseils techniques et de conception)