JavaScriptでマルチスレッドを実装する(実際のまたは偽の)いくつかの異なる方法の比較に取り組んでいます。私の知る限り、WebワーカーとGoogle Gears WorkerPoolだけが実際のスレッドを提供できます(つまり、実際の並列実行で複数のプロセッサに分散します)。私は次の方法を見つけました:
yield()
を使用してタスクを切り替える
もう1つのスレッドを待機しているスレッドでsetInterval()
(または他の非ブロッキング関数)を使用する
google Gears WorkerPoolスレッドを使用する(プラグイン付き)
html5 Webワーカーを使用する
私は関連する質問を読み、上記の方法のいくつかのバリエーションを見つけましたが、それらの質問のほとんどは古いので、いくつかの新しいアイデアがあるかもしれません。
私は疑問に思っています-JavaScriptで他にどのようにマルチスレッドを実現できますか?他の重要な方法はありますか?
UPDATE:コメントで指摘されているように、私が実際に意味したのは同時実行性でした。
UPDATE 2:Silverlight + JScriptがマルチスレッドをサポートしているという情報を見つけましたが、これを確認できません。
更新3:Googleは廃止されたGears: http://code.google.com/apis/gears/api_workerpool.html
Webワーカー 。これはW3C標準(現時点ではワーキングドラフト)であり、プラグインは必要ありません。
この仕様は、Webアプリケーションの作成者がメインページと並行してスクリプトを実行するバックグラウンドワーカーを生成できるようにするAPIを定義しています。
この仕様では、真の同時実行性を実現するために、ワーカーを複数のコアに分散させることについても説明しています(これはブラウザーのJavaScriptエンジンによって見えないように処理されます)。
マルチコアCPUが普及しているため、パフォーマンスを向上させる1つの方法は、計算コストのかかるタスクを複数のワーカー間で分割することです。 [1]の例では、1から10,000,000の数値ごとに実行される計算コストの高いタスクが、10人のサブワーカーにファームアウトされます。
yield()
とsetInterval()
は、後で発生するようにスケジュールするだけで、他のものと同時に実行されることはありません。
私は疑問に思っています-JavaScriptで他にどのようにマルチスレッドを実現できますか?他の重要な方法はありますか?
明示的なループや直接の関数呼び出しがないJavaScriptコードにコードを変換することができます。代わりに、コードは、スレッドエンジンによって管理される小さなnits実行に分割されます。私のサンプルコードでは、ループを持つ関数がどのように変換されるかを示していますが、例を単純にするために、関数呼び出しのメカニズムを省略しています。
変換のプロセスは基本的に、分割点でsplittingコードによって機能します。これらの分割ポイントは、関数呼び出しとループです(上記で説明)。例ではオブジェクトとキーを使用しましたが、unitsがstackをオブジェクト変数として(つまり、this.foo = bar
ではなくstack["foo"] = bar
を使用して保存)。
たとえば、次のコード:
// 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;
}
}
...このようなものに:
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};
}
}
Multithread.js は、Webワーカーをラップし、大部分の作業を代行してくれる、JSでの本当に簡単なマルチスレッド化のためのライブラリです。 :)
JavaScriptでのマルチスレッドの直接サポートはありません。ただし、いくつかのアイデアと方法を適用することでこれを実現できます。
次のような方法があります。
var id = window.timeout("javascript code", time);
ここでは、JavaScriptコードが指定された時間の後に呼び出され、使用できます
window.clearTimeout(id);
クリア用。これにより、偽の同時実行を実現できます。
q:他にどのようにJavaScriptで並行性を実現できますか
非同期または「非ブロッキング」タイプのメソッドを使用できます。これは、node.jsシステムに関する大きな話題の1つです。正確にはマルチスレッドではありませんが、高速になる傾向があります。