Javascript `Module`变量';将Pthread编译为worker时,Emscripten中的s机制
在将Pthread编译为webworker+Wasm时,我被Emsripten中的Javascript `Module`变量';将Pthread编译为worker时,Emscripten中的s机制,javascript,c,pthreads,web-worker,emscripten,Javascript,C,Pthreads,Web Worker,Emscripten,在将Pthread编译为webworker+Wasm时,我被Emsripten中的模块变量弄糊涂了 有一个简单的Pthread代码,它只在每个线程的共享变量sum中添加1。(simple.c附在末尾。) 我们可以使用该命令编译Pthread代码: $emcc simple.c-s USE\u PTHREADS=1-s PTHREAD\u POOL\u SIZE=4-o simple.html Emscripten将生成simple.html,simple.js,simple.worker.js
模块
变量弄糊涂了
有一个简单的Pthread代码,它只在每个线程的共享变量sum
中添加1
。(simple.c
附在末尾。)
我们可以使用该命令编译Pthread代码:
$emcc simple.c-s USE\u PTHREADS=1-s PTHREAD\u POOL\u SIZE=4-o simple.html
Emscripten将生成simple.html
,simple.js
,simple.worker.js
,和simple.wasm
在simple.worker.js
中,有一个片段:
//simple.worker.js
var模块={};
// ...
模块['InstanceWasm']=函数(信息,接收实例){
//从主线程发布的模块实例化。
//我们可以在worker中使用sync实例化。
var instance=new WebAssembly.instance(模块['wasmModule'],信息);
//我们不再需要这个模块了;新的线程将从主线程中产生。
模块['wasmModule']=null;
receiveInstance(instance);//第二个“module”参数在这里故意为null,我们不需要在这里保留对module对象的引用。
出口退税;
};
注意,它在worker中声明var Module={}
,并定义Module['instancewasm']
但是,Module['instancewasm']
仅由simple.js
调用,代码片段如下所示:
//simple.js
变量模块={}
// ...
if(模块['instancewasm']){
试一试{
var exports=Module['instancewasm'](信息,receiveInstance);
出口退税;
}捕获(e){
错误('Module.instancewasm回调失败,错误为:'+e);
返回false;
}
}
// ...
正如我们所看到的,simple.js
也声明了var Module={}
AFAIK,VAR
全局变量不能跨主线程及其工作线程访问我不明白为什么simple.js
可以调用Module['instancewasm']
作为simple.js的Module
和simple.worker.js的Module
应该不是一回事。
Pthread代码:
//simple.c
#包括
#包括
#包括
#定义numthrds4
#定义放大率1e9
类型定义结构
{
int-thread_-id;
双倍*和;
}精氨酸;
pthread_t callThd[NUMTHRDS];
pthread_mutex_t mutexsum;
void*count\u pi(void*arg)
{
Arg*数据=(Arg*)Arg;
int thread\u id=data->thread\u id;
双*和=数据->和;
pthread_mutex_lock(&mutexsum);
*总和+=1;
pthread_mutex_unlock(&mutexsum);
printf(“线程%d:sum=%f\n”,线程id,*sum);
pthread_exit((void*)0);
}
int main(int argc,char*argv[])
{
pthread_mutex_init(&mutexsum,NULL);
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr,pthread_CREATE_JOINABLE);
double*sum=malloc(sizeof(*sum));
*总和=0;
Arg Arg[NUMTHRDS];
对于(int i=0;i
主程序将自身发送给工作者
// 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);
}
因此,
模块
不是共享的,而是独立初始化的。太奇怪了。为什么emscripten将main.js
设置为条目;然后使用它来设置worker并再次在worker中导入自身?我的意思是,我们不能不这样做就分离逻辑吗?你知道为什么吗?我不确定,但是分离它们的ifdef条件编译逻辑可能是一项困难的工作。我懂了。我认为这会让代码很难阅读。不管怎样,多亏了我。