【问题标题】:WebAssembly blocks the web worker thread tooWebAssembly 也阻塞了 web worker 线程
【发布时间】:2018-11-17 23:12:15
【问题描述】:

这个和上一个问题WebAssembly in async code有关

基本上,这个问题是关于 WebAssembly 阻塞主线程的问题,而这个问题的答案是将 WebAssembly 代码移动到 web worker 中。这行得通。

现在的问题是 WebAssembly 阻塞了 worker 上的 onmessage()。

我长时间运行的 WebAssembly 代码具有 play()、pause()、stop() 等函数。play() 会定期检查暂停标志和停止标志以确定 play() 是否应该返回。 pause() 和 stop() 用于设置这些标志。

JavaScript 主线程调用 postMessage() 向 worker 发送消息,worker 进一步调用 play()。

由于 onmessage() 被阻塞,worker 将没有机会接收更多消息来执行 pause() 或 stop() 直到 play() 完成。这将破坏暂停/停止的目的。

WebAssembly 似乎无法支持播放/暂停/停止的简单用例。

有什么建议或建议吗?

顺便说一句,该用例得到了已停产的 Google PNaCl 的良好支持。

谢谢。

【问题讨论】:

    标签: asynchronous emscripten webassembly


    【解决方案1】:

    简而言之:即使网络工作者线程被阻塞,网络工作者也不会忽略消息。

    所有浏览器事件,包括 web worker postMessage()/onmessage() 事件都已排队。这是 JavaScript 的基本理念(onmessage() 是在 JS 中完成的,即使你使用 WebAssembly)。请查看"Concurrency model and Event Loop" from MDN 了解更多详情。

    那么在你的情况下会发生什么,当onmessage() 被阻塞时,来自主线程postMessage() 的事件会自动排队。当工作线程中的单个 onmessage() 作业完成时,来自工作事件队列的工作线程将检查是否在完成之前调用了 postMessage(),如果有则捕获消息。因此,您无需担心这种情况,只要 onmessage() 作业需要大约 10 秒,并且您会在队列中获得数百个事件。

    这就是异步执行在浏览器中无处不在的方式。

    【讨论】:

      【解决方案2】:

      考虑到您的目标是最近的浏览器 (WebAssembly),您很可能依赖 SharedArrayBuffer 和 Atomics。查看这些解决方案 Is it possible to pause/resume a web worker externally? ,在您的情况下需要在 WebAssembly 内部处理(Atomics.wait 部分)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-12-24
        • 2019-09-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-07-01
        相关资源
        最近更新 更多