摘要:實現線程鎖中增加了和,利用它們可以實現鎖,即頁面主線程和線程間的鎖。位置的值減去并保存到位置,返回原值。有了上面的和就可以實現一個很簡單的線程鎖,簡單來說,就是利用在多個線程間共享控制位,當控制位為已鎖時,則暫停線程,這些操作都依賴。
JavaScript 實現線程鎖
ECMAScript 2018 中增加了 SharedArrayBuffer 和 Atomics ,利用它們可以實現鎖(Lock),即頁面主線程和 Web Worker 線程間的鎖。
SharedArrayBufferSharedArrayBuffer(以下簡稱為SAB) 是一個可以主線程和 Web Worker 線程間共享數據的對象,即同一個 SAB 可以被多個線程讀寫。
let sab = new SharedArrayBuffer(1024); worker.postMessage(sab);
SAB 避免了多個線程間為了傳遞數據而進行數據拷貝,但同時缺引入了經典的數據訪問「沖突」:
// 線程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] = ? :( }
這時候就需要原子操作。
AtomicsAtomics 可以實現對于 SAB 原子訪問,其包含很多操作。
我們下面會用到的:
Atomics.store(typedArray, index, value):向 SAB 的 index 位置賦值 value。
Atomics.wait(typedArray, index, value[, timeout]):驗證 Int32Array 的 index 位置是否為給定的 value,是則睡眠(阻塞),否則繼續執行。
Atomics.wake(typedArray, index, count):喚醒 Int32Array 的 index 位置上wait 隊列(Atomics.wait 產生)。
Atomics.sub(typedArray, index, value):index 位置的值減去 value 并保存到 index 位置,返回原值。
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 的 }參考
Shared memory and atomics
A Taste of JavaScript’s New Parallel Primitives
https://www.akkadia.org/drepper/futex.pdf
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/84044.html
摘要:以多線程的形式,允許單個任務分成不同的部分進行運行。提供協調機制,一方面防止進程之間和線程之間產生沖突,另一方面允許進程之間和線程之間共享資源。主線程會不斷的重復上訴過程。 眾所周知,js是單線程的,說到線程,我們首先來仔細辨析一下線程和進程的知識。 一、進程與線程 阮一峰老師的一篇文章寫的很好 cpu會給當前進程分配資源,進程是資源分配的最小單位,進程的資源會分配給線程使用,線程是C...
摘要:如果期間有其它線程更新了,則會先拿到新的值重新運算一次多運算的競爭條件這些運算符成功避免了單運算中的競爭條件。 作者:Lin Clark 譯者:Cody Chan 原帖鏈接:Avoiding race conditions in SharedArrayBuffers with Atomics 這是圖解 SharedArrayBuffers 系列的第三篇: 內存管理碰撞課程 圖...
閱讀 3118·2021-11-15 18:14
閱讀 1773·2021-09-22 10:51
閱讀 3283·2021-09-09 09:34
閱讀 3505·2021-09-06 15:02
閱讀 1013·2021-09-01 11:40
閱讀 3186·2019-08-30 13:58
閱讀 2523·2019-08-30 11:04
閱讀 1081·2019-08-28 18:31