#thread #parallel #replace

wasm_thread

针对 wasm32 目标的 std 线程替代品

7 个版本

0.3.0 2024年3月17日
0.2.0 2022年5月27日
0.1.4 2020年11月8日
0.1.3 2020年10月5日

并发 中排名 56

Download history 1838/week @ 2024-05-01 632/week @ 2024-05-08 699/week @ 2024-05-15 1579/week @ 2024-05-22 2074/week @ 2024-05-29 2295/week @ 2024-06-05 4438/week @ 2024-06-12 1718/week @ 2024-06-19 1242/week @ 2024-06-26 1189/week @ 2024-07-03 2359/week @ 2024-07-10 4398/week @ 2024-07-17 2399/week @ 2024-07-24 1872/week @ 2024-07-31 3254/week @ 2024-08-07 1479/week @ 2024-08-14

每月下载量 9,708
用于 28 Crates(其中 5 个直接使用)

Apache-2.0 或 MIT 许可

47KB
581 行代码(不包括注释)

wasm_thread

License Cargo Documentation

针对 wasm32 目标的 std::thread 替代品。

此 crate 尝试尽可能接近地复制 std::thread API。具体来说,它不需要您捆绑工作脚本,并自动解析 wasm-bindgen 隧道 URL。

请注意,某些 API 可能仍然缺失,甚至可能由于 wasm 限制而无法实现。

作为库使用

  • wasm_thread 添加到您的 Cargo.toml 文件。
  • 此项目支持 wasm-pack 目标 webno-modules。如果构建为 web,请启用 crate 功能 es_modules。否则,此包默认将针对 no-modules
  • use std::thread 替换为 use wasm_thread as thread。注意,某些 API 可能缺失。
  • 使用 wasm-pack 正常构建或根据您的项目调整 build_wasm.sh

关于 wasm 限制的说明

  • 为了使多个 wasm 实例共享相同的内存,需要 SharedArrayBuffer。这意味着网页的 COOP 和 COEP 安全头需要设置(参见 Mozilla 的文档)。这些可以通过调整 web 服务器设置或使用 service worker 来启用。
  • 主线程上的任何阻塞 API(如 thread.join()futures::block_on() 等)将使浏览器在锁定保持期间冻结。这也冻结了任何代理函数,这意味着工作线程生成、网络获取和其他类似的异步 API 也会阻塞,并可能导致死锁。为了避免这种情况,要么在工作线程中运行您的 main(),要么使用异步 future。
  • 原子锁(具体为 i32.atomic.wait)在主线程上会引发panic。这意味着 mutex.lock() 可能会崩溃。解决方案与上面相同。
  • Web workers 通常通过提供脚本URL来创建,然而,为了避免打包脚本,这个库使用URL编码的blob web_worker.js 来避免HTTP fetch。仍然需要 wasm_bindgen 生成的 .js shim脚本,并使用一个 hack 来获取其URL。如果在这个设置中由于某些原因不起作用,请报告一个问题或使用 Builder::wasm_bindgen_shim_url() 来指定显式URL。
  • 有关wasm线程的更多信息,请参阅这篇博客文章raytrace-parallel 示例。

替代方案

对于更高级别的线程解决方案,请参阅wasm-bindgen-rayon,它允许在Web浏览器中利用固定大小的线程池。

运行示例

简单

本地

  • 只需cargo run --example simple

wasm-bindgen

  • 安装nightly工具链和依赖项
rustup toolchain install nightly
rustup component add rust-src --toolchain nightly
cargo install wasm-bindgen-cli
  • 使用 ./build_wasm.sh(bash)或 ./build_wasm.ps1(PowerShell)构建。这个自定义构建步骤是必需的,因为预构建的标准库还没有对原子操作的支持。有关更多信息,请参阅这里
  • 使用跨源隔离启用HTTP服务examples目录,并在浏览器中打开simple.html。检查控制台输出。您可以使用cargo install sfz作为基本HTTP服务器,并使用sfz examples --coi提供服务。

wasm-pack

  • 安装 wasm-pack
cargo install wasm-pack
  • 对于针对 web 的示例,使用 ./examples-wasm-pack/web-build.sh 构建,对于针对 no-modules 的示例,使用 ./examples-wasm-pack/web-build-no-module.sh 构建。
  • 分别通过HTTP服务./examples-wasm-pack/module./examples-wasm-pack/no-module,然后在浏览器中打开simple.html。检查控制台输出。

示例输出

本地

hi number 1 from the spawned thread ThreadId(2)!
hi number 1 from the main thread ThreadId(1)!
hi number 1 from the spawned thread ThreadId(3)!
hi number 2 from the main thread ThreadId(1)!
hi number 2 from the spawned thread ThreadId(2)!
hi number 2 from the spawned thread ThreadId(3)!

Wasm

hi number 1 from the main thread ThreadId(1)!
hi number 2 from the main thread ThreadId(1)!
hi number 1 from the spawned thread ThreadId(2)!
hi number 1 from the spawned thread ThreadId(3)!
hi number 2 from the spawned thread ThreadId(2)!
hi number 2 from the spawned thread ThreadId(3)!

如您所见,wasm线程仅在 main() 返回后才会创建,因为浏览器事件循环无法在主线程阻塞时继续。

许可

根据您的选择,许可如下:

贡献

除非您明确声明,否则您提交给工作的任何有意包含的贡献,根据Apache-2.0许可定义,应如上双许可,不附加任何其他条款或条件。

依赖项

~8–10MB
~191K SLoC