emscripten与线程

emscripten与线程一 首先要让示例跑起来运行以下命令 编译一个简单的示例 em tests worker api worker cpp sBUILD AS WORKER 1 sEXPORTED FUNCTIONS one oworker jsem tests worker api main cpp omain html 浏览器打开 main html 应该可以看到结果了

一、首先要让示例跑起来

运行以下命令,编译一个简单的示例:

em++ tests/worker_api_worker.cpp -s BUILD_AS_WORKER=1 -s EXPORTED_FUNCTIONS="['_one']" -o worker.js
em++ tests/worker_api_main.cpp -o main.html

浏览器打开main.html,应该可以看到结果了。

备注:所有示例的编译方法,可以参见 emscripten\tests\runner.py 文件。

二、emscripten_call_worker的参数

调用worker的方法通过这个emscripten_call_worker函数实现,看看它的参数定义:

/* * Asynchronously call a worker. * * The worker function will be called with two parameters: a * data pointer, and a size. The data block defined by the * pointer and size exists only during the callback and * _cannot_ be relied upon afterwards - if you need to keep some * of that information around, you need to copy it to a safe * location. * * The called worker function can return data, by calling * emscripten_worker_respond(). If called, and if a callback was * given, then the callback will be called with three arguments: * a data pointer, a size, and * an argument that was provided * when calling emscripten_call_worker (to more easily associate * callbacks to calls). The data block defined by the data pointer * and size behave like the data block in the worker function - * it exists only during the callback. * * @funcname the name of the function in the worker. The function * must be a C function (so no C++ name mangling), and * must be exported (EXPORTED_FUNCTIONS). * @data the address of a block of memory to copy over * @size the size of the block of memory * @callback the callback with the response (can be null) * @arg an argument to be passed to the callback */ void emscripten_call_worker(worker_handle worker, const char *funcname, char *data, int size, void (*callback)(char *, int, void*), void *arg);

参数说明:

worker — 句柄

funcname — worker里的函数名称,C风格,并且使用EXPORTED_FUNCTIONS导出

data — 数据地址

size — 数据大小

callback — 回调函数(当异步执行完成时,回调这个函数,同时会把data 和size 返回,但是不要期望此data地址还是传入的data地址)

arg — 回调函数的参数

令人郁闷的地方:

(1)传入的data 和 size,是传值,而不是指针和引用,因为emscripten是将data复制一份,发给worker

(2)callback收到的data,仍然是传值,是数据的拷贝

(3)所以不要期望主程序与worker之间能够共享指针。

三、一点点体会

1、emscripten_create_worker = 在线程池中创建了一个线程

2、emscripten_call_worker = 主程序发送消息给线程(在js中,实际体现在onmessage函数里)

onmessage = function(msg) { //确定消息函数   var func = Module['_' + msg.data['funcName']]; if (!func) throw 'invalid worker function to call: ' + msg.data['funcName']; var data = msg.data['data']; if (data) { //复制传入的参数数据 if (!data.byteLength) data = new Uint8Array(data); if (!buffer || bufferSize < data.length) { if (buffer) _free(buffer); bufferSize = data.length; buffer = _malloc(data.length); } HEAPU8.set(data, buffer); } inWorkerCall = true; workerResponded = false; workerCallbackId = msg.data['callbackId']; if (data) { //调用相应的消息函数  func(buffer, data.length); } else { func(0, 0); } inWorkerCall = false; }

3、emscripten_worker_respond = 线程发送消息给主程序

四、线程交互的麻烦


1、web worker里面无法调用webgl

2、worker里生成图片,再传回主函数

3、线程如何暂停(不是terminate)?线程工作时是不响应onmessage的。

找到一个解决方案:http://msmvps.com/blogs/theproblemsolver/archive/2012/05/02/html5-background-tasks-using-web-workers.aspx

还有一个示例:http://demos.html5support.nl/WebWorkers/Chunked

Using  a chunking algorithm

The solution is to use a chunking algorithm. This algorithm brakes the calculation into different groups and use the setTimeout() API to execute the next chunk after a small delay. The result of using setTimeout() is that the message posted can be read and we can actually pause and resume the worker execution. Using a chunking algorithm out background worker JavaScript looks like this:


版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/200266.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月20日 上午11:11
下一篇 2026年3月20日 上午11:11


相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号