Signatur
Beschreibung
Atomics.or() liest den Wert an einer Position eines Integer-TypedArrays, verknüpft ihn bitweise per OR mit value und schreibt das Ergebnis zurück. Diese drei Schritte laufen als eine unteilbare Operation ab. Kein anderer Thread (Worker) kann dazwischen schreiben, auch wenn der Speicher über einen SharedArrayBuffer geteilt wird.
Typischerweise setzt man damit Flags oder Bitmasken in gemeinsam genutztem Speicher, etwa „Worker 3 ist fertig“ oder „Ressource belegt“. Mit dem normalen Ausdruck arr[i] |= mask würde man dagegen eine Race Condition riskieren: Zwei Worker lesen gleichzeitig denselben alten Wert, und eines der gesetzten Bits geht verloren.
Der Rückgabewert ist der Wert vor der Operation. Daran sieht man, ob ein Bit schon gesetzt war. So lässt sich zum Beispiel ein einfaches „Test-and-Set“ bauen.
Die Methode funktioniert auch mit einem gewöhnlichen ArrayBuffer. Atomar im Sinne mehrerer Threads ist sie aber nur mit einem SharedArrayBuffer.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $typedArray Pflicht | Int8Array|Uint8Array|Int16Array|Uint16Array|Int32Array|Uint32Array|BigInt64Array|BigUint64Array | Ganzzahliges TypedArray, meist auf einem SharedArrayBuffer. Float32Array, Float64Array und Uint8ClampedArray sind nicht erlaubt. |
|
| $index Pflicht | number | Position im typedArray, an der die OR-Verknüpfung stattfindet. |
|
| $value Pflicht | number|bigint | Zahl, mit der bitweise OR verknüpft wird. Bei BigInt64Array und BigUint64Array muss sie ein bigint sein. |
Rückgabewert
typedArray[index] vor der Operation.Beispiele
Grundlegende Verwendung
const sab = new SharedArrayBuffer(4);
const ta = new Uint8Array(sab);
ta[0] = 0b0101; // 5
const alt = Atomics.or(ta, 0, 0b0011); // 3
console.log(alt); // alter Wert
console.log(Atomics.load(ta, 0)); // 5 | 3 = 7
Status-Flags mehrerer Worker setzen
// main.js
const sab = new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT);
const status = new Int32Array(sab);
const workerAnzahl = 4;
for (let id = 0; id < workerAnzahl; id++) {
const w = new Worker('worker.js');
w.postMessage({ sab, id });
}
// worker.js
self.onmessage = ({ data: { sab, id } }) => {
const status = new Int32Array(sab);
// ... Arbeit erledigen ...
Atomics.or(status, 0, 1 << id); // eigenes Bit atomar setzen
Atomics.notify(status, 0);
};
Test-and-Set: prüfen, ob ein Bit schon gesetzt war
const flags = new Int32Array(new SharedArrayBuffer(4));
const BELEGT = 0b1;
const tryAcquire = () => (Atomics.or(flags, 0, BELEGT) & BELEGT) === 0;
console.log(tryAcquire()); // erster Aufruf bekommt die Ressource
console.log(tryAcquire()); // schon belegt
Atomics.and(flags, 0, ~BELEGT); // freigeben
console.log(tryAcquire());
Mit BigInt64Array für 64-Bit-Masken
const big = new BigInt64Array(new SharedArrayBuffer(8));
Atomics.or(big, 0, 1n << 40n);
console.log(Atomics.load(big, 0));
// Wichtig · Fallstricke
- TypeError, wenn das Array kein erlaubtes Integer-TypedArray ist oder bei BigInt-Arrays kein
bigintübergeben wird. Zahlen und BigInts lassen sich nicht mischen. - RangeError, wenn
indexaußerhalb des Arrays liegt. valuewird auf den Elementtyp gekürzt. BeiUint8Arrayzählen z. B. nur die unteren 8 Bits.SharedArrayBuffersteht im Browser nur in einem cross-origin isolated Kontext zur Verfügung. Dafür braucht es die HeaderCross-Origin-Opener-Policy: same-originundCross-Origin-Embedder-Policy: require-corp. Prüfen lässt sich das mitself.crossOriginIsolated.- Innerhalb eines einzelnen Threads bringt
Atomics.or()gegenüber|=keinen Vorteil, nur etwas Mehraufwand. - Die Methode wird in allen modernen Browsern und ab Node.js 8.10 unterstützt.