Ber*_*ard 6 javascript locking synchronous web-worker webassembly
虽然我理解JavaScript本质上是单线程的,并且通常对这些事情不满意,但我想知道是否有任何方法可以让WebWorker等到主线程提供一些数据而不破坏WebWorker的调用堆栈.
由于这是一个有趣的项目,我可以使用新技术和不能在旧浏览器上可靠运行的东西,我不介意深奥的黑客,只要它们工作.
我考虑过的其他一些解决方案:
在循环中连续轮询LocalStorage,直到预定密钥上有数据.这似乎是有效的,因为即使在循环中轮询时,其他线程的LocalStorage更新应该对当前线程可见,从所有关于LocalStorage的线程安全性的讨论判断并且有多个选项卡写入相同的LocalStorage键.这种方法的缺点是它不是真正"等待",即工作线程仍然消耗在LocalStorage上的全部CPU使用率.虽然LocalStorage通常使用锁实现,但是长时间不能持有LocalStorage锁(锁被释放一次getItem或setItem返回).
ECMAScript 6 yield.这在这里不起作用,因为它需要调用堆栈中的所有函数(直到你想要屈服的地方)被标记为生成器函数.我想暂停我的WebWorker的地方有一个包含WebAssembly函数的调用堆栈,它不能标记为生成器函数.
IndexedDB的.这不起作用,因为IndexedDB不支持同步请求.
我知道这个类似的问题,但是这个问题专门讨论了这个onmessage事件,并在2012年之前被问到,yield并且引入了WebAssembly.
有没有办法以某种方式模拟WebWorker线程上的锁,否则,它会等到某些数据可用?
编辑:请注意,SharedArrayBuffer在默认情况下,在所有主要的浏览器禁用(于2018年1月5日)响应幽灵.
JavaScript的SharedArrayBuffer听起来非常适合您:
出于您的目的,您希望WebWorker等待数据可用.有了SharedArrayBuffer您可以使用SPINLOOP(Atomics.load直到值的变化),但它会更好地使用Atomics.wait,直到其他工作人员向您发送Atomics.wake.这个后来的API受到Linux的futex的启发,如果你正在等待的值不可用,它将不会不必要地旋转.
// Main program:
var w = new Worker("worker.js")
var sab = new SharedArrayBuffer(1024);
w.postMessage(sab);
var i = new Int32Array(sab);
// Maybe wait for worker.js to message back that it's ready through onmessage?
//
// Fill i with some data!
// ...
//
// Notify one worker, at location 0, with value 1.
Atomics.store(i, 0, 1);
Atomics.wake(i, 0, /* notify count */ 1);
// worker.js:
var sab;
var i;
onmessage = function (ev) {
sab = ev.data;
var i = new Int32Array(sab);
}
// Maybe tell the main program we're ready through postMessage?
//
// ...
// Wait until location 0 isn't value 0
Atomics.wait(i, 0, 0);
Run Code Online (Sandbox Code Playgroud)
记住:阻止主线程是个坏主意!如果您这样做,您的网站将无法响应.你的问题是关于阻止一个工人,但读者可能有兴趣等待主线程.别!
最终将在WebAssembly中提供非常相似且兼容的API .这是一个早期的提案草案.当我说兼容时:我们希望WebAssembly能够SharedArrayBuffer像JavaScript 一样使用它,并且两者都能够通过它无缝地进行通信.
| 归档时间: |
|
| 查看次数: |
1356 次 |
| 最近记录: |