Start · Sprachen · JavaScript · Referenz · Atomics.pause()

Atomics.pause()

Methode

Signalisiert der CPU, dass der aufrufende Code in einer kurzen Warteschleife (Spin-Loop) auf eine gemeinsam genutzte Ressource wartet. Die Ausführung wird dabei nicht blockiert.

seit JavaScript ES2025 – Chrome/Edge 133+, Firefox 137+, Safari 18 Kategorie: method-property

Signatur

Atomics.pause(durationHint)

Beschreibung

Atomics.pause() ist eine Hilfe für sehr kurzes Warten. Beim sogenannten Spin-Locking fragt ein Thread in einer engen Schleife immer wieder ab, ob eine Sperre frei ist, etwa über Atomics.compareExchange(). Ruft man in so einer Schleife Atomics.pause() auf, kann die JavaScript-Engine einen passenden Prozessorbefehl nutzen, zum Beispiel PAUSE auf x86 oder YIELD auf ARM. Das spart Energie, verhindert Engpässe in der CPU-Pipeline und gibt Hyper-Threading-Geschwistern mehr Rechenzeit.

Anders als Atomics.wait() legt pause() den Thread nicht schlafen. Die Methode gibt die Kontrolle nicht an das Betriebssystem ab und ändert kein Speicherverhalten. Sie ist also keine Synchronisations-Primitive, sondern nur ein Hinweis zur Leistung. Deshalb darf sie auch im Haupt-Thread aufgerufen werden, wo Atomics.wait() verboten ist.

Mit dem optionalen Parameter durationHint lässt sich ein exponentielles Backoff bauen: Je größer der Wert, desto länger darf die Engine pausieren. Wie lange genau, legt die Implementierung fest. Typischerweise kombiniert man ein paar kurze Spin-Runden mit Atomics.pause(), bevor man, falls nötig, mit Atomics.wait() richtig schlafen geht.

Parameter

Name Typ Default Beschreibung
$durationHint number | undefined undefined Optionaler ganzzahliger Hinweis, wie lange pausiert werden soll. Größere Werte bedeuten tendenziell längere Pausen; der genaue Effekt hängt von der Implementierung ab. Alles, was keine Ganzzahl und nicht undefined ist, löst einen TypeError aus.

Rückgabewert

Typ
undefined
Beschreibung
Gibt immer undefined zurück.

Beispiele

Spin-Lock mit exponentiellem Backoff (im Worker)

// Gemeinsamer Speicher: Index 0 = Lock (0 = frei, 1 = belegt)
const sab = new SharedArrayBuffer(4);
const lock = new Int32Array(sab);

const acquire = () => {
  let spins = 0;
  // Versuche, den Lock von 0 auf 1 zu setzen
  while (Atomics.compareExchange(lock, 0, 0, 1) !== 0) {
    // Der CPU signalisieren: wir warten; Pause wächst mit jedem Versuch
    Atomics.pause(spins);
    spins = Math.min(spins * 2 || 1, 1024);
  }
};

const release = () => {
  Atomics.store(lock, 0, 0);
};

acquire();
console.log('Lock erhalten:', Atomics.load(lock, 0));
release();
console.log('Lock freigegeben:', Atomics.load(lock, 0));
Lock erhalten: 1 Lock freigegeben: 0

Hybrid: erst kurz spinnen, dann mit Atomics.wait schlafen

// Läuft in einem Worker (Atomics.wait ist im Haupt-Thread verboten)
const sab = new SharedArrayBuffer(4);
const state = new Int32Array(sab);
const MAX_SPINS = 100;

const lock = () => {
  for (let i = 0; i < MAX_SPINS; i++) {
    if (Atomics.compareExchange(state, 0, 0, 1) === 0) return 'per Spin';
    Atomics.pause(i);
  }
  // Lange Wartezeit: Thread wirklich schlafen legen
  while (Atomics.compareExchange(state, 0, 0, 1) !== 0) {
    Atomics.wait(state, 0, 1);
  }
  return 'per wait';
};

const unlock = () => {
  Atomics.store(state, 0, 0);
  Atomics.notify(state, 0, 1);
};

console.log(lock());
unlock();
per Spin

Gültige und ungültige Argumente

console.log(Atomics.pause());      // ohne Hinweis
console.log(Atomics.pause(10));    // Ganzzahl-Hinweis

try {
  Atomics.pause(1.5);
} catch (err) {
  console.log(err.name);
}

try {
  Atomics.pause('10');
} catch (err) {
  console.log(err.name);
}
undefined undefined TypeError TypeError

// Wichtig · Fallstricke

  • Nur ein Hinweis, keine Synchronisation: Atomics.pause() sorgt weder für eine Speicherreihenfolge noch für gegenseitigen Ausschluss. Die eigentliche Sperre müssen Sie immer mit Atomics.compareExchange(), Atomics.store() usw. umsetzen.
  • Keine feste Dauer: Wie lange tatsächlich pausiert wird, hängt von Engine und CPU ab und kann sogar null sein. Für zeitgesteuertes Warten eignet sich die Methode nicht.
  • Strenge Typprüfung: Kommazahlen, Strings, NaN oder Infinity als durationHint lösen einen TypeError aus. Es gibt keine automatische Umwandlung.
  • Haupt-Thread: Der Aufruf ist dort erlaubt. Langes Spinnen blockiert aber trotzdem die Oberfläche. Im Haupt-Thread sollte man auf Atomics.waitAsync() ausweichen.
  • Kompatibilität: Die Methode ist neu (ES2025). Für ältere Umgebungen empfiehlt sich eine Prüfung wie typeof Atomics.pause === 'function' mit einem leeren Fallback. Bei SharedArrayBuffer muss die Seite im Browser außerdem cross-origin isolated sein, also die Header COOP und COEP senden.