20

所以我有这个非常递归的函数,我想在我的代码中使用它。问题是它并没有真正利用双核机器,因为 js 是单线程的。我曾尝试使用网络工作者,但对多核编程知之甚少。有人会向我指出一些可以解释它是如何完成的材料。我用谷歌搜索找到这个示例链接,但如果没有文档,它并没有多大帮助!=/

如果有人能告诉我如何在没有网络工作者的情况下完成这项工作,我会很高兴!那真是太棒了!=)

在 whatwg 上看到了这个链接。这真的很奇怪,因为它解释了如何在 webworkers 等中使用多核编程,但是在我的 chrome 浏览器上执行它会引发错误。其他浏览器也是如此。

错误:9Uncaught ReferenceError:Worker 未在 worker.js 中定义

4

3 回答 3

12

更新(2018-06-21):对于来这里寻找 JavaScript 中的多核编程的人,不一定是浏览器 JavaScript(为此,答案仍然适用):Node.js 现在支持背后的多线程功能标志(--experimental-workers):发布信息相关问题


在我的脑海中写下这个,不保证源代码。请对我放轻松。

据我所知,你不能真正用 JavaScript 在线程中编程。Webworkers 是多道程序的一种形式;然而 JavaScript 本质上是单线程的(基于事件循环)。

webworker 是独立的执行线程,因为它与启动它的脚本共享任何内容;没有引用脚本的全局对象(通常在浏览器中称为“窗口”),也没有引用任何主脚本的变量,除了发送到线程的数据。

把网络工作者想象成一个小“服务器”,它被问到一个问题并提供一个答案。您只能将字符串发送到该服务器,它只能解析字符串并将其计算的内容发回。

// in the main script, one starts a worker by passing the file name of the 
// script containing the worker to the constructor. 
var w = new Worker("myworker.js");

// you want to react to the "message" event, if your worker wants to inform
// you of a result. The function typically gets the event as an argument. 
w.addEventListener("message",
    function (evt) {
        // process evt.data, which is the message from the 
        // worker thread
        alert("The answer from the worker is " + evt.data);
    });

然后,您可以使用其 postMessage() 方法向该线程发送消息(字符串):

w.postMessage("Hello, this is my message!");

示例工作脚本(“echo”服务器)可以是:

// this is another script file, like "myworker.js"
self.addEventListener("message", 
    function (evt) {
        var data = JSON.parse(evt.data);
        /* as an echo server, we send this right back */
        self.postMessage(JSON.stringify(data))
    })

您发布到该线程的任何内容都将被解码、重新编码并发回。当然,您可以在两者之间进行任何您想做的处理。该工人将保持活跃;你可以调用terminate()它(在你的主脚本中;那是w.terminate())来结束它或调用self.close()你的工作人员。

总结一下:你可以做的是将你的函数参数压缩成一个 JSON 字符串,该字符串使用postMessage“在另一端”(在工作人员中)发送、解码和处理。计算结果被发送回您的“主”脚本。

解释为什么这不容易:更多的交互实际上是不可能的,并且这种限制是故意的。因为共享资源(工作程序和主脚本都可见的对象)会同时受到两个线程的干扰,所以您需要管理对该资源的访问(即锁定)以防止竞争条件.

消息传递、无共享的方法并不为人所知,主要是因为大多数其他编程语言(例如 C 和 Java)使用在同一地址空间上运行的线程(而其他,例如 Erlang,则不)。考虑一下:

  • 由于相关的死锁/竞争条件复杂性,使用互斥锁(一种互斥机制)编写更大的项目真的很困难。这是可以让成年男人哭泣的东西!
  • 与进行消息传递、无共享语义相比,这真的很容易。代码是隔离的;你确切地知道你的工人有什么,你的工人有什么。死锁和竞争条件是不可能实现的!

试试看;它能够做有趣的事情,可能是你想要的。请记住,据我所知,它是否利用多核仍然是实现定义的。

注意。我刚刚获悉,至少有一些实现会为您处理消息的 JSON 编码。

因此,要回答您的问题(以上都是;tl;dr 版本):不,没有网络工作者,您将无法做到这一点。但是除了浏览器支持之外,Web Worker 并没有什么真正的问题,就像 HTML5 一样。

于 2012-05-30T13:09:57.860 回答
5

据我记得,这只有在新的 HTML5 标准下才有可能。关键字是“网络工作者”

也可以看看:

HTML5:JavaScript 网络工作者

使用 HTML5 Web Workers 的 JavaScript 线程

于 2010-12-15T12:19:21.983 回答
4

网络工作者是客户端的答案。对于 NodeJS,有很多方法。最受欢迎 - 使用pm2或类似工具生成多个进程。运行单个进程并生成/分叉子进程。你可以在这些周围搜索一下,会发现很多示例和策略。

所有浏览器都已经很好地支持了 Web Worker。https://caniuse.com/#feat=webworkers

API 和示例:https ://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers

在此处输入图像描述

于 2018-10-09T04:10:08.320 回答