问题描述
在将Pthread编译为Web Worker + Wasm时,我对Emsripten中的const actuallyAnObject = chat.usersArray;
let realArray = actuallyAnObject.map((item,i) => item); // throws an error
console.log(Object.keys(actuallyAnObject); // displays in the console correctly
let keys = Object.keys(actuallyAnObject); // throws an error
let array = [];
Object.keys(actuallyAnObject).forEach((key) => { // throws an error
array.push({[key]: actuallyAnObject[key]});
});
console.log("actuallyAnObject['0'] : ",actuallyAnObject["0"]); // displays correctly
console.log("typeof actuallyAnObject : ",typeof actuallyAnObject); // object
变量感到困惑
有一个简单的Pthread代码,只需在每个线程的共享变量Module
中添加1
。 (sum
附加在末尾。)
我们可以使用以下命令来编译Pthread代码:
simple.c
Emscripten将生成$ emcc simple.c -s USE_PTHREADS=1 -s PTHREAD_POOL_SIZE=4 -o simple.html
,simple.html
,simple.js
和simple.worker.js
。
simple.worker.js
请注意,它在工作程序中声明了// simple.worker.js
var Module = {};
// ...
Module['instantiateWasm'] = function(info,receiveInstance) {
// Instantiate from the module posted from the main thread.
// We can just use sync instantiation in the worker.
var instance = new WebAssembly.Instance(Module['wasmModule'],info);
// We don't need the module anymore; new threads will be spawned from the main thread.
Module['wasmModule'] = null;
receiveInstance(instance); // The second 'module' parameter is intentionally null here,we don't need to keep a ref to the Module object from here.
return instance.exports;
};
,并定义了var Module = {}
。
但是,Module['instantiateWasm']
仅由Module['instantiateWasm']
调用,其代码段如下所示:
simple.js
我们可以看到,//simple.js
var Module = {}
// ...
if (Module['instantiateWasm']) {
try {
var exports = Module['instantiateWasm'](info,receiveInstance);
return exports;
} catch(e) {
err('Module.instantiateWasm callback Failed with error: ' + e);
return false;
}
}
// ...
也声明了simple.js
。
AFAIK,var Module = {}
全局变量无法在主线程及其工作线程之间进行访问。 我不明白为什么VAR
可以像simple.js
的{{1}}那样调用Module['instantiateWasm']
,而Module
的{{1}}却不能一样的东西。
Pthread代码:
simple.js
解决方法
主程序将自身发送给工作人员。
// simple.js
// Ask the new worker to load up the Emscripten-compiled page. This is a heavy operation.
worker.postMessage({
'cmd': 'load',// If the application main .js file was loaded from a Blob,then it is not possible
// to access the URL of the current script that could be passed to a Web Worker so that
// it could load up the same file. In that case,developer must either deliver the Blob
// object in Module['mainScriptUrlOrBlob'],or a URL to it,so that pthread Workers can
// independently load up the same main application file.
'urlOrBlob': Module['mainScriptUrlOrBlob'] || _scriptDir,'wasmMemory': wasmMemory,'wasmModule': wasmModule,'DYNAMIC_BASE': DYNAMIC_BASE,'DYNAMICTOP_PTR': DYNAMICTOP_PTR
});
然后由工人导入。
// simple.worker.js
if (typeof e.data.urlOrBlob === 'string') {
importScripts(e.data.urlOrBlob);
} else {
var objectUrl = URL.createObjectURL(e.data.urlOrBlob);
importScripts(objectUrl);
URL.revokeObjectURL(objectUrl);
}
因此Module
不被共享,但是它是独立初始化的。