Web Worker 比本地线程更重还是更轻

Is web worker heavier or lighter than a native thread

Web Worker 是否只是浏览器创建的普通本机线程 运行 并通过消息队列与其他浏览器线程通信?还是创建的时候不包含其他东西?

我正在查看 emscripten 中的 experimental support of pthread,C++ 中的多线程将在编译后转换为 web worker。但它是否具有与本机代码相同的性能水平?毕竟细粒度多线程是 C++ 中的一个关键特性。

目前,WebWorker 相当重量级,因为 VM 复制了一堆内部状态(有时甚至为 worker 重新编写 JIT 代码)。该状态 比本机线程的几个 MiB 初始堆栈 space 和关联状态大 很多。

其中一些可以通过实现来解决,我预计如果 SharedArrayBuffer or WebAssembly + threads 变得流行,那么浏览器引擎将想要优化一些东西。

话虽如此,您问题的结尾暗示了对线程开销的误解,以及 SharedArrayBuffer 的提案(Emscripten 依赖它来支持 pthreads)是如何工作的。 WebWorkers 目前很重,但它们可以通过 SAB 进行通信,其方式与本机代码(如 C++)完全相同:通过访问完全相同的内存,在相同的虚拟地址。 SAB 向 JavaScript 添加了一种新的 ArrayBuffer,当您 postMessage 将它交给另一个工作人员时,它不会被绝育。当您使用 std::atomic.

时,多个工作人员可以以与 C++ 代码完全相同的方式查看其他工作人员对缓冲区的更新

同时,根据定义,worker 不能阻塞主线程,因此更有 "native" 的感觉。某些 Web API 并非对所有工作人员都可用,但这种情况一直在发生变化。如果您例如编写游戏并在不同线程中进行网络/音频/渲染/AI/输入。网络正在慢慢找到自己做这些事情的方式。

细节有点棘手

SAB 目前仅支持非原子访问和顺序一致的访问(即目前唯一可用的 Atomic 访问与 C++ 的 std::memory_order_seq_cst 相同)。进行非原子访问应该与 C++ 的非原子访问一样高效(这里我不会涉及大的编译器警告),并且使用 Atomic 应该与 C++ 的 std::atomic 默认一样高效(即 std::memory_order_seq_cst)。 C++ 有 5 个 SAB 目前不支持的其他内存顺序(relaxedconsumeacquirereleaseacq_rel)。这些其他内存顺序允许本机代码在某些情况下更快,但更难正确和可移植地使用。它们可能会添加到 SAB 的未来更新中,例如通过 this issue.

SAB 还支持 Futex 本机程序在幕后依赖它来实现高效 mutex

与 C++ 相比,还有更棘手的细节,I've detailed some of them 但还有更多。