javascript - HTML5/JS - 启动多个 webworker

标签 javascript arrays html performance web-worker

我目前正在编写一个程序,我必须在其中处理巨大的数组。但是我可以拆分这些数组。我现在的计划是,在不同的网络 worker 中处理数组。然而,我从未与他们合作过,确实有几个问题:

1. 我将如何运行多个网络 worker ?我尝试了一个看起来像这样的 for 循环:

for(i = 0; i < eD.threads; i++){
    //start workers here 
    var worker = new Worker("js/worker/imageValues.js");
    worker.postMessage(brightness, cD.pixels[i]);
}

我确实得到了错误,无法克隆该对象。这似乎合乎逻辑。我想将它们保存在数组中会更好?

2. 我如何控制所有人都完成了他们的工作? (我需要重新组装数组并稍后使用它)

3.有多少网络 worker 真正带来了改进?

4.除了MDN-entry,还有进阶教程吗?

谢谢!

最佳答案

1. How would I run several web workers? I tried a for-loop looking like that:

创建多个 worker 没有问题,即使您不在数组中跟踪它们也是如此。见下文。

2. How would I control that all have finished their work? (I need to reassembly the array and work with it later)

他们可以在完成后将结果发回给您。示例如下。

3. How many web workers really bring an improvement?

一根绳子有多长? :-) 答案将完全取决于运行它的目标机器。现在很多人的机器上都有四个或更多的内核。当然,这台机器也在做很多其他的事情。您必须针对目标环境进行调整。

4. Is there any advanced tutorial, besides the MDN-entry?

关于 web worker 的“高级”并不多。 :-) 我找到了 this article就足够了。

这是一个运行 5 个 worker 并等待他们完成的示例:

主窗口:

(function() {
    var n, worker, running;

    display("Starting workers...");
    running = 0;
    for (n = 0; n < 5; ++n) {
        workers = new Worker("worker.js");
        workers.onmessage = workerDone;
        workers.postMessage({id: n, count: 10000});
        ++running;
    }
    function workerDone(e) {
        --running;
        display("Worker " + e.data.id + " is done, result: " + e.data.sum);
        if (running === 0) { // <== There is no race condition here, see below
            display("All workers complete");
        }
    }
    function display(msg) {
        var p = document.createElement('p');
        p.innerHTML = String(msg);
        document.body.appendChild(p);
    }
})();

worker.js:

this.onmessage = function(e) {
    var sum, n;
    sum = 0;
    for (n = 0; n < e.data.count; ++n) {
        sum += n;
    }
    this.postMessage({id: e.data.id, sum: sum});
};

关于不存在的竞争条件:如果您考虑真正的抢占式线程,那么您可能会想:我可以创建一个 worker,将 running 递增到 1 ,然后在我创建下一个 worker 之前,我可以从第一个 worker 那里得到它已经完成的消息,将 running 减少到 0,并错误地认为所有 worker 完成了。

这在 web worker 工作的环境中是不可能发生的。尽管环境欢迎随时启动 worker,并且 worker 可以在启动 worker 的代码完成之前完成,但唯一能做的就是queue 对主 JavaScript 线程的 workerDone 函数的调用。没有先发制人。因此,我们知道在第一次调用 workerDone 实际执行之前,所有 worker 都已启动。因此,当 running0 时,我们知道它们都已完成。

最后说明:在上面,我使用 onmessage = ... 来连接事件处理程序。当然,这意味着我只能在我正在处理的对象上拥有一个事件处理程序。如果您需要为 message 事件设置多个处理程序,请使用 addEventListener。所有支持 web worker 的浏览器都支持 addEventListener(您不必担心 IE attachEvent 问题)。

关于javascript - HTML5/JS - 启动多个 webworker,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18191779/

相关文章:

html - IMG 高度设置为 60%,但父 DIV 仍然延伸到 100%

javascript - 如何通过菜单选项清除 Internet Explorer v8、v9 中的本地存储

javascript - 如何从 module.exports 访问函数

Javascript 视差在 Mac 上很慢

arrays - 抛出异常的要点

arrays - Perl 读取文件并拆分为数组

html - <h1> 标签之前和之后的响应式图像

javascript - 在 react 渲染中使用异步和等待

javascript - 如何设置一个新类不适用于 Bootstrap 和 jQuery?

javascript - 我正在制作抽认卡游戏,但 "Next"按钮不起作用