我们正在构建使用 pthreads 作为模块的 emscr 应用程序。 以下是链接器选项:
-sWASM=1 -sINITIAL_MEMORY=134217728 -sMAX_WEBGL_VERSION=2 -sUSE_GLFW=3 -sFULL_ES3 -sEXIT_RUNTIME -sASYNCIFY -lembind -sEXPORT_ES6=1 -sUSE_ES6_IMPORT_META=1 -sMODULARIZE=1 -sEXPORT_NAME=FooModule -sENVIRON MENT=网络,工作人员-sUSE_PTHREADS= 1 -sPTHREAD_POOL_SIZE=4 -sOFFSCREENCANVAS_SUPPORT=1 -sOFFSCREEN_FRAMEBUFFER -pthread -sSHARED_MEMORY
运行此构建时,我们开始在 JS 方面遇到各种运行时错误。需要注意的是,使用上面列出的所有命令构建应用程序(除了负责构建模块的命令之外)都可以正常工作。一旦我们将 wasm 模块化,它似乎就无法加载工作线程。 这是我们从浏览器收到的错误消息:
还有这个:
在检查生成的 .js 文件时,我们发现这可能与以下事实有关:
allocateUnusedWorker()
函数需要指定类型: module ,像这样:
new Worker(new URL("FooWEB.worker.js", import.meta.url), {
type: "module",
})
相反,它这样做:
new Worker(new URL("FooWEB.worker.js", import.meta.url))
此外,
Module["canvas"]
似乎未定义。
Module["PThread"].receiveObjectTransfer(e.data);
- 这似乎没有被调用,这导致画布无法初始化。
因此,Web Worker 永远不会收到带有“run”的消息,该消息应该调用
Module["PThread"].receiveObjectTransfer(e.data);
然后receiveObjectTransfer
中的FooWEB.js
,它似乎负责分配
Module["canvas"] = GL.offscreenCanvases[data.moduleCanvasId].offscreenCanvas;
Module["canvas"].id = data.moduleCanvasId;
从未被调用,这导致了:
___pthread_create_js
找不到 Module["canvas"]
并且抛出
err(
'pthread_create: could not find canvas with ID "' +
name +
'" to transfer to thread!'
);
我在构建配置中遗漏了什么吗?
这些选项:
-sEXPORT_ES6=1 -sUSE_ES6_IMPORT_META=1 -sMODULARIZE=1
用于生成要捆绑的ESM模块。您使用捆绑器吗?如果您不使用捆绑器,请不要生成 ESM 模块并让 emscripten 完成其工作 - 这是它做得非常好的事情。如果您使用捆绑器,那么您的捆绑器应该负责
import.meta
并转译工作线程。