JavaScript 多线程
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7639224/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
JavaScript multithreading
提问by Chris Hasiński
I'm working on comparison for several different methods of implementing (real or fake) multithreading in JavaScript. As far as I know only webworkers and Google Gears WorkerPool can give you real threads (ie. spread across multiple processors with real parallel execution). I've found the following methods:
我正在比较几种在 JavaScript 中实现(真实或虚假)多线程的不同方法。据我所知,只有 webworkers 和 Google Gears WorkerPool 可以为您提供真正的线程(即分布在具有真正并行执行的多个处理器上)。我找到了以下方法:
switch between tasks using
yield()
use
setInterval()
(or other non-blocking function) with threads waiting one for anotheruse Google Gears WorkerPool threads (with a plugin)
use html5 web workers
使用在任务之间切换
yield()
使用
setInterval()
(或其他非阻塞函数)与线程等待另一个使用 Google Gears WorkerPool 线程(带插件)
使用 html5 网络工作者
I read related questions and found several variations of the above methods, but most of those questions are old, so there might be a few new ideas.
我阅读了相关问题并发现了上述方法的几种变体,但这些问题大多是旧的,因此可能会有一些新的想法。
I'm wondering - how else can you achieve multithreading in JavaScript? Any other important methods?
我想知道 - 你还能如何在 JavaScript 中实现多线程?还有其他重要的方法吗?
UPDATE:As pointed out in comments what I really meant was concurrency.
更新:正如评论中指出的,我真正的意思是并发。
UPDATE 2:I found information that Silverlight + JScript supports multithreading, but I'm unable to verify this.
更新 2:我发现 Silverlight + JScript 支持多线程的信息,但我无法验证这一点。
UPDATE 3:Google deprecated Gears: http://code.google.com/apis/gears/api_workerpool.html
更新 3:Google 弃用 Gears:http: //code.google.com/apis/gears/api_workerpool.html
采纳答案by s4y
Web Workers. They're a W3C standard (well, a working draft at the moment) for exactly this, and require no plugins:
网络工作者。它们是一个 W3C 标准(嗯,目前是一个工作草案)正是为了这个,并且不需要插件:
This specification defines an API that allows Web application authors to spawn background workers running scripts in parallel to their main page.
该规范定义了一个 API,允许 Web 应用程序作者生成后台工作人员,与他们的主页并行运行脚本。
The specification also discusses spreading workers across multiple cores, for true concurrency (this is handled invisibly by the browser's JavaScript engine):
该规范还讨论了将 worker 分散到多个核心,以实现真正的并发(这由浏览器的 JavaScript 引擎不可见地处理):
With multicore CPUs becoming prevalent, one way to obtain better performance is to split computationally expensive tasks amongst multiple workers. In [one] example, a computationally expensive task that is to be performed for every number from 1 to 10,000,000 is farmed out to ten subworkers.
随着多核 CPU 的普及,获得更好性能的一种方法是在多个工作人员之间拆分计算成本高的任务。在[一个]示例中,将要为从 1 到 10,000,000 的每个数字执行的计算成本高的任务分配给 10 个子工人。
yield()
and setInterval()
only schedule things to happen later, they don't run concurrently with anything else.
yield()
并且setInterval()
只安排事情稍后发生,它们不会与其他任何事情同时运行。
回答by Keldon Alleyne
I'm wondering - how else can you achieve multithreading in JavaScript? Any other important methods?
我想知道 - 你还能如何在 JavaScript 中实现多线程?还有其他重要的方法吗?
You can have your code transformed into JavaScript code that doesn't have any explicit loops or direct function calls, instead code is divided into small unitsof execution that are managed by a threading engine. In my example code I show how a function with loops would be transformed but I've omitted the mechanism for function calls just to keep the example simple.
您可以将代码转换为没有任何显式循环或直接函数调用的 JavaScript 代码,而是将代码划分为由线程引擎管理的小执行单元。在我的示例代码中,我展示了如何转换带有循环的函数,但为了使示例简单,我省略了函数调用机制。
The process of transformation basically works by splittingcode at division points. These division points are function calls and loops (as demonstrated above). In the example I've used objects and keys but it may be much easier on the browser's JavaScript engines if the unitsstored the stackas an object variable (i.e. storing using this.foo = bar
instead of stack["foo"] = bar
).
转换过程基本上是通过在分割点分割代码来工作的。这些划分点是函数调用和循环(如上所示)。在示例中,我使用了对象和键,但如果单元将堆栈存储为对象变量(即存储 usingthis.foo = bar
而不是stack["foo"] = bar
),则在浏览器的 JavaScript 引擎上可能会容易得多。
For example the following code:
例如下面的代码:
// Phoney method purely to demonstrate structure
function Foo() {
var i,
sum = 0,
accumulator_list = [],
accumulator_modulus = [],
kMaxAccumulatorCount = 100;
// Calculate accumulations
for(i = 0; i < kMaxAccumulatorCount; ++i) {
current_accumulator = GetNextAccumulator()
accumulator_list[i] = current_accumulator;
sum = sum + current_accumulator;
}
// Calculate accumulator modulus
for(i = 0; i < kMaxAccumulatorCount; ++i) {
current_accumulator = accumulator_list[i];
accumulator_modulus[i] = current_accumulator % kMaxAccumulatorCount;
}
}
... into something like this:
...变成这样:
function Foo_A(caller,stack) {
var stack = {};
stack["i"] = undefined;
stack["sum"] = 0;
stack["accumulator_list"] = [];
stack["accumulator_modulus"] = [];
stack["kMaxAccumulatorCount"] = 100;
stack["i"] = 0;
return {caller: caller, stack: stack, next=Foo_B};
}
function Foo_B(caller, stack) {
stack["current_accumulator"] = GetNextAccumulator();
stack["accumulator_list"][stack["i"]] = stack["current_accumulator"];
stack["sum"] = stack["sum"] + stack["current_accumulator"];
// For-loop condition satisfied ?
if(stack["i"] < stack["kMaxAccumulatorCount"]) {
++stack["i"];
return {caller: caller, stack: stack, next:Foo_B};
} else {
// Initialise the next for loop.
stack["i"] = 0;
return {caller: caller, stack: stack, next:Foo_C};
}
}
function Foo_C(caller, stack) {
stack["current_accumulator"] = stack["current_accumulator"][stack["i"]];
stack["accumulator_modulus"][stack["i"]] = stack["current_accumulator"] % stack["kMaxAccumulatorCount"];
// For-loop condition satisfied ?
if(stack["i"] < stack["kMaxAccumulatorCount"]) {
++stack["i"];
return {caller: caller, stack: stack, next:Foo_C};
} else {
// Function has finished so the next will be null. When the thread-engine sees this it simulates the behaviour of a return, pops its virtual stack and returns execution to the caller
return {caller: caller, stack: stack, next:null};
}
}
回答by kwh
Multithread.jsis a library for really easy multithreading in JS that wraps Web Workers and does the majority of your work for you. :)
Multithread.js是一个非常简单的 JS 多线程库,它包装了 Web Workers 并为您完成大部分工作。:)
回答by kwh
There is no direct support for multithreading in JavaScript. However you can achieve this by applying some ideas and method.
JavaScript 中没有直接支持多线程。但是,您可以通过应用一些想法和方法来实现这一点。
There are methods like:
有这样的方法:
var id = window.timeout("javascript code", time);
here the JavaScript code is called after the specifed time and we can use
这里 JavaScript 代码在指定时间之后被调用,我们可以使用
window.clearTimeout(id);
for clearing. By this we can achieve fake concurrency.
用于清算。通过这种方式,我们可以实现假并发。
回答by BenG
q: how else can you achieve concurrency in Javascript
问:在 Javascript 中你还能如何实现并发
You can use async or 'non-blocking' type methods. This has one of the major buzzes about the node.js system. It's not exactly multithreaded, but it does tend to be faster.
您可以使用异步或“非阻塞”类型的方法。这是关于 node.js 系统的主要讨论之一。它并不完全是多线程的,但它确实会更快。