SharedArrayBuffer
Baseline Widely available
This feature is well established and works across many devices and browser versions. It’s been available across browsers since December 2021.
L'objet SharedArrayBuffer
est utilisé afin de représenter un tampon de données binaires brutes générique de longueur fixe. Il est semblable à l'objet ArrayBuffer
, mais peut ici être utilisé pour créer différentes vues sur une même mémoire partagée. À la différence d'un ArrayBuffer
, un SharedArrayBuffer
n'est pas un objet transférable.
Description
Allouer et partager la mémoire
Pour partager une zone mémoire entre plusieurs objets
SharedArrayBuffer
d'un agent à un autre (ici un agent correspond au programme principal de la page web ou à l'un de ses web workers), on utilisera postMessage()
et le clonage structuré.
L'algorithme de clonage structuré permet d'envoyer des objets SharedArrayBuffers
et TypedArrays
vers des objets SharedArrayBuffer
. Dans les deux cas, l'objet SharedArrayBuffer
est transmis au récepteur, ce qui crée un nouvel objet SharedArrayBuffer
, privé, au sein de l'agent qui reçoit (comme avec ArrayBuffer
). Cependant, le bloc de mémoire référencé par les deux objets SharedArrayBuffer
est bien le même bloc. Aussi, si un agent interagit avec cette zone, l'autre agent pourra voir les modifications.
let sab = new SharedArrayBuffer(1024);
worker.postMessage(sab);
Mettre à jour et synchroniser la mémoire partagée avec les opérations atomiques
La mémoire partagée peut être créée et mise à jour de façon simultanée entre les workers et le thread d'exécution principal. Selon le système (le processeur, le système d'exploitation, le navigateur), cela peut prendre du temps avant que le changement soit propagé sur l'ensemble des contextes. Pour que la synchronisation s'effectue, on doit utiliser des opérations atomiques.
Les API qui utilisent des objets SharedArrayBuffer
Contraintes de sécurité
La mémoire partagée et les chronomètres de haute précision ont été désactivés début 2018 suite à la vulnérabilité Spectre. En 2020, une nouvelle approche, sécurisée, a été mise en place afin de réactiver la mémoire partagée. En suivant quelques règles de sécurité, postMessage()
ne lève plus d'exception pour les objets SharedArrayBuffer
et une mémoire partagée entre les threads est disponible.
Pour commencer, le document doit être mis à disposition dans un contexte sécurisé.
Pour les documents de plus haut niveau, deux en-têtes HTTP doivent être utilisés pour isoler le site des origines tierces :
Cross-Origin-Opener-Policy
avec la valeursame-origin
(ce qui protège l'origine des éventuels attaquants)Cross-Origin-Embedder-Policy
avec la valeurrequire-corp
(ce qui protège les éventuelles victimes de votre origine)
Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp
Pour vérifier si l'isolation envers les origines tierces a réussi, vous pouvez vérifier la propriété crossOriginIsolated
qui est disponible dans les contextes de la fenêtre et des workers :
if (crossOriginIsolated) {
// on poste le SharedArrayBuffer
} else {
// on fait autre chose
}
Voir aussi les changements prévus quant à la mémoire partagée pour les différents navigateurs.
Obligation d'utiliser l'opérateur new
Les constructeurs SharedArrayBuffer
doivent être utilisés avec l'opérateur new
. Si on appelle un constructeur SharedArrayBuffer
comme une fonction, sans new
, cela lèvera une exception TypeError
.
var sab = SharedArrayBuffer(1024);
// TypeError: appeler le constructeur natif SharedArrayBuffer sans
// new est interdit
var sab = new SharedArrayBuffer(1024);
Constructeur
-
Crée un nouvel objet
SharedArrayBuffer
.
Propriétés des instances
-
La taille du tableau, exprimée en octets. Celle-ci est déterminée à la construction du tableau et ne peut pas être modifiée par la suite, elle est accessible en lecture seule uniquement.
Méthodes des instances
-
Renvoie un nouvel objet
SharedArrayBuffer
dont le contenu et une copie des octets de l'objetSharedArrayBuffer
courant entre l'indice de début (inclus) et l'indice de fin (exclus). Si l'un des deux indices est négatif, il est relatif à la fin du tableau plutôt qu'au début.
Exemples
Créer un nouvel objet SharedArrayBuffer
let sab = new SharedArrayBuffer(1024);
Découper un objet SharedArrayBuffer
sab.slice(); // SharedArrayBuffer { byteLength: 1024 }
sab.slice(2); // SharedArrayBuffer { byteLength: 1022 }
sab.slice(-2); // SharedArrayBuffer { byteLength: 2 }
sab.slice(0, 1); // SharedArrayBuffer { byteLength: 1 }
Utiliser un tampon WebGL
const canvas = document.querySelector("canvas");
const gl = canvas.getContext("webgl");
const buffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
gl.bufferData(gl.ARRAY_BUFFER, sab, gl.STATIC_DRAW);
Spécifications
Specification |
---|
ECMAScript Language Specification # sec-sharedarraybuffer-objects |
Compatibilité des navigateurs
BCD tables only load in the browser
Voir aussi
Atomics
ArrayBuffer
- Les tableaux typés en JavaScript
- Les Web Workers
parlib-simple
— une bibliothèque qui fournit des abstractions pour synchroniser et distribuer des tâches- La mémoire partagée — un rapide tutoriel (en anglais)
- A Taste of JavaScript's New Parallel Primitives — Mozilla Hacks (en anglais)