JavaScript 實現線程鎖

JavaScript 實現線程鎖

ECMAScript 2018 中增長了 SharedArrayBufferAtomics ,利用它們能夠實現鎖(Lock),即頁面主線程和 Web Worker 線程間的鎖。javascript

SharedArrayBuffer

SharedArrayBuffer(如下簡稱爲SAB) 是一個能夠主線程和 Web Worker 線程間共享數據的對象,即同一個 SAB 能夠被多個線程讀寫html

let sab = new SharedArrayBuffer(1024);
worker.postMessage(sab);

SAB 避免了多個線程間爲了傳遞數據而進行數據拷貝,但同時缺引入了經典的數據訪問「衝突」:java

// 線程A
let sharedBuffer = new SharedArrayBuffer(1024);
let sharedArray = new Int32Array(sab);

let worker = new Worker("browser-worker.js");
worker.postMessage(sab);

sharedArray[1] = 1;

// 線程B
onmessage = function (e) {
  let sharedBuffer = e.data;
  let sharedArray = new Int32Array(sab);

  sharedArray[1] = 10;
  sharedArray[2] = sharedArray[1] + sharedArray[1];
  // sharedArray[2] = ? :(
}

這時候就須要原子操做git

Atomics

Atomics 能夠實現對於 SAB 原子訪問,其包含不少操做github

咱們下面會用到的:算法

Atomics.store(typedArray, index, value):向 SAB 的 index 位置賦值 value。post

Atomics.wait(typedArray, index, value[, timeout]):驗證 Int32Array 的 index 位置是否爲給定的 value,是則睡眠(阻塞),不然繼續執行。atom

Atomics.wake(typedArray, index, count):喚醒 Int32Array 的 index 位置上wait 隊列(Atomics.wait 產生)。線程

Atomics.sub(typedArray, index, value):index 位置的值減去 value 並保存到 index 位置,返回原值code

Atomics.compareExchange(typedArray, index, expectedValue, replacementValue):若是 index 位置的值爲 expectedValue,則與 replcementValue 交換,返回原值

Lock

有了上面的 SAB 和 Atomics 就能夠實現一個很「簡單」的線程鎖,

簡單來講,就是利用 SAB 在多個線程間共享控制位,當控制位爲「已鎖」時,則暫停線程,這些操做都依賴 Atomics。

注意:這個算法是 Futex,參考了Futexes Are Tricky

// lock 
if ((c = Atomics.compareExchange(SAB, index, 0, 1)) !== 0) { // 不爲0,說明其餘人持鎖
  do {
       // 若是依舊得不到鎖
    if (c === 2 || Atomics.compareExchange(SAB, index, 1, 2) != 0) {
      Atomics.wait(SAB, index, 2); // 暫停
    }
    // 再次嘗試獲取鎖
  } while ((c = Atomics.compareExchange(SAB, index, 0, 2)) !== 0)
}

// unlock
let v0 = Atomics.sub(SAB, index, 1);
// 此時擁有鎖,狀態爲1或2
if (v0 != 1) {
  Atomics.store(SAB, index, 0); // 釋放鎖
  Atomics.wake(SAB, index, 1); // 喚醒一個 wait 的
}

參考

  1. Shared memory and atomics

  2. A Taste of JavaScript’s New Parallel Primitives

  3. https://www.akkadia.org/drepper/futex.pdf

相關文章
相關標籤/搜索