web worker 比原生线程更重还是更轻

Posted

技术标签:

【中文标题】web worker 比原生线程更重还是更轻【英文标题】:Is web worker heavier or lighter than a native thread 【发布时间】:2016-11-02 15:59:55 【问题描述】:

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

我正在查看 emscripten 中的 experimental support of pthread,C++ 中的多个线程在编译后将被转换为网络工作者。但它会拥有与原生代码相同的性能水平吗?毕竟细粒度的多线程是 C++ 的一个关键特性。

【问题讨论】:

我猜网络工作者只是伪装的线程池 【参考方案1】:

目前,WebWorkers 是相当重量级的,因为 VM 复制了一堆其内部状态(有时甚至为工作人员重新 JIT 代码)。该状态大于原生线程的初始堆栈空间和关联状态的几 MiB。

其中一些问题可以通过实现来解决,我希望如果 SharedArrayBuffer 或 WebAssembly + threads 变得流行,那么浏览器引擎将需要优化。

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

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

细节有点复杂

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

SAB 还支持Futex,本机程序在底层依赖它来实现高效的mutex

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

【讨论】:

以上是关于web worker 比原生线程更重还是更轻的主要内容,如果未能解决你的问题,请参考以下文章

比 SpringBoot更快,更轻,更小!

判断apache的工作模式是prefork模式还是worker模式

web worker原理

linux mpm模式用prefork好还是worker好

如何直接从原生 JavaScript 前端与 Emscripten Web Worker 交互

web worker