これは意図的な設計上の決定なのか、それとも現在のブラウザーの問題であり、今後のバージョンで修正されるのでしょうか?
16 に答える
ブラウザーの JavaScript インタープリターはシングルスレッド (AFAIK) であるため、JavaScript はマルチスレッドをサポートしていません。Google Chrome でさえ、単一の Web ページの JavaScript を同時に実行することはできません。これは、既存の Web ページで大規模な同時実行の問題が発生するためです。Chrome が行うことは、複数のコンポーネント (異なるタブ、プラグインなど) を別々のプロセスに分離することだけですが、1 つのページに複数の JavaScript スレッドがあるとは想像できません。
ただし、提案されsetTimeout
たように、ある種のスケジューリングと「偽の」同時実行を許可するために使用できます。これにより、ブラウザはレンダリング スレッドの制御を取り戻し、指定されsetTimeout
たミリ秒後に提供された JavaScript コードを開始します。これは、操作の実行中にビューポート (表示されるもの) を更新できるようにする場合に非常に便利です。座標などをループし、それに応じて要素を更新するだけで、開始位置と終了位置が表示され、その間には何も表示されません。
JavaScript で抽象化ライブラリを使用して、同じ JavaScript インタープリターによってすべて管理されるプロセスとスレッドを作成できるようにします。これにより、次の方法でアクションを実行できます。
- プロセス A、スレッド 1
- プロセス A、スレッド 2
- プロセス B、スレッド 1
- プロセス A、スレッド 3
- プロセス A、スレッド 4
- プロセス B、スレッド 2
- プロセスAを一時停止
- プロセス B、スレッド 3
- プロセス B、スレッド 4
- プロセス B、スレッド 5
- プロセスAを開始
- プロセス A、スレッド 5
これにより、何らかの形式のスケジューリングが可能になり、並列処理、スレッドの開始と停止などが偽装されますが、真のマルチスレッドにはなりません。言語自体に実装されることはないと思います。真のマルチスレッドは、ブラウザーが単一ページのマルチスレッド (または複数のコア) を実行できる場合にのみ有用であり、その問題ははるかに大きいためです。余分な可能性よりも。
JavaScript の将来については、こちらをご覧ください: https://developer.mozilla.org/presentations/xtech2006/javascript/
JavaScript マルチスレッド (いくつかの制限あり) はこちらです。Google は Gears のワーカーを実装しており、ワーカーは HTML5 に含まれています。ほとんどのブラウザーは、この機能のサポートを既に追加しています。
ワーカーとの間でやり取りされるすべてのデータがシリアル化/コピーされるため、データのスレッド セーフが保証されます。
詳細については、次を参照してください。
従来、JS は短くて実行速度の速いコードを対象としていました。大規模な計算を行う場合は、サーバー上で実行します。ブラウザーで長時間実行されるJS+HTMLアプリが重要な処理を実行するという考えはばかげています。
もちろん、今はそれを持っています。しかし、ブラウザーが追いつくには少し時間がかかります。ほとんどのブラウザーはシングル スレッド モデルを中心に設計されており、それを変更するのは簡単ではありません。Google Gears は、バックグラウンド実行を分離することを要求することで、多くの潜在的な問題を回避します。DOM を変更せず (これはスレッドセーフではないため)、メイン スレッドによって作成されたオブジェクトにアクセスしません (同上)。制限はありますが、これはブラウザの設計を簡素化し、経験の浅い JS コーダーがスレッドをいじることに伴うリスクを軽減するため、近い将来最も実用的な設計になる可能性があります...
Javascript でマルチスレッドを実装しないのはなぜですか? プログラマーは、自分が持っているツールを使ってやりたいことが何でもできます。
だから、私が開いている他のすべてのウェブサイトが私のブラウザをクラッシュさせるほど簡単に誤用されるツールを彼らに与えないようにしましょう. これを単純に実装すると、MS が IE7 の開発中に非常に多くの頭痛の種を引き起こした領域に直行することになります。アドオンの作成者は、スレッド モデルをすばやく緩く扱ったため、プライマリ スレッドでオブジェクトのライフサイクルが変更されたときに明らかになった隠れたバグが発生しました。 . 悪い。IE 用のマルチスレッド ActiveX アドオンを作成している場合は、その領域が付属していると思います。それ以上進む必要があるという意味ではありません。
この決定の論理的根拠はわかりませんが、setTimeout を使用してマルチスレッド プログラミングの利点のいくつかをシミュレートできることは知っています。複数のプロセスが同時に処理を行っているように見せることができますが、実際にはすべてが 1 つのスレッドで行われます。
関数に少し作業をさせてから、次のように呼び出します。
setTimeout(function () {
... do the rest of the work...
}, 0);
また、その他の必要なこと (UI の更新、アニメーション画像など) は、機会があれば行われます。
言語がマルチスレッドをサポートしていないのはなぜですか、それともブラウザーの JavaScript エンジンがマルチスレッドをサポートしていないのはなぜですか?
最初の質問に対する答えは、ブラウザの JavaScript はサンドボックスで、マシンや OS に依存しない方法で実行されることを意図しているためです。マルチスレッドのサポートを追加すると、言語が複雑になり、言語が OS に密接に結び付きすぎます。
Node.js 10.5+ は実験的な機能としてワーカー スレッドをサポートします ( --experimental-workerフラグを有効にして使用できます): https://nodejs.org/api/worker_threads.html
したがって、ルールは次のとおりです。
- I/O バウンド opsを実行する必要がある場合は、内部メカニズム (コールバック/プロミス/非同期待機) を使用します。
- CPU バウンド opsを実行する必要がある場合は、ワーカー スレッドを使用します。
ワーカー スレッドは、長寿命のスレッドであることを目的としています。つまり、バックグラウンド スレッドを生成してから、メッセージ パッシングを介してスレッドと通信します。
それ以外の場合、無名関数で重い CPU 負荷を実行する必要がある場合は、ワーカー スレッドを中心に構築された小さなライブラリであるhttps://github.com/wilk/microjobを使用できます。
マットbが言ったように、質問はあまり明確ではありません. 言語でのマルチスレッド サポートについて尋ねていると仮定すると、現在ブラウザーで実行されているアプリケーションの 99.999% には必要ないためです。本当に必要な場合は、回避策があります (window.setTimeout を使用するなど)。
一般に、マルチスレッド化は、(不変データのみを使用するなどの) 追加の制限を設けない限り、正しく行うのが非常に非常に非常に非常に非常に困難です (難しいと言いましたか?)。
Intel は Javascript でのマルチスレッドに関するオープンソースの調査を行っており、最近の GDC 2012 で紹介されました。ビデオへのリンクは次のとおりです。研究グループは、主に Intel チップ セットと Windows OS に焦点を当てた OpenCL を使用しました。このプロジェクトのコードネームは RiverTrail で、コードは GitHub で入手できます。
いくつかの便利なリンク:
現在、一部のブラウザーはマルチスレッドをサポートしています。そのため、必要に応じて特定のライブラリを使用できます。たとえば、次の資料を表示します。
https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers (バックグラウンド スレッドをサポート);
Javascript はシングルスレッド言語です。これは、1 つのコール スタックと 1 つのメモリ ヒープがあることを意味します。予想どおり、コードを順番に実行し、次のコードに進む前にコードの実行を終了する必要があります。それは同期ですが、時にはそれが有害になる可能性があります。たとえば、関数の実行に時間がかかるか、何かを待機する必要がある場合、その間すべてがフリーズします。
マルチスレッドをサポートしていないのは実装です。現在、Google Gears は、外部プロセスを実行することにより、何らかの形式の同時実行を使用する方法を提供していますが、それだけです。
Google が本日リリースする予定の新しいブラウザ (Google Chrome) は、一部のコードを分割して並列実行します。
コア言語は、もちろん Java などと同じサポートを持つことができますが、Erlang の同時実行性のようなサポートは、地平線から遠く離れています。
スレッド同期の適切な言語サポートがなければ、新しい実装を試すことすら意味がありません。既存の複雑なJSアプリ(ExtJSを使用するものなど)は予期せずクラッシュする可能性がありますが、synchronized
キーワードなどがないと、正しく動作する新しいプログラムを作成することも非常に困難または不可能です。
私が聞いた限りでは、Google Chrome にはマルチスレッドの JavaScript が搭載されるため、これは「現在の実装」の問題です。
HTML5 によってもたらされる webworkers を使用すると、javascript を使用したマルチスレッドが明らかに可能になります。
Webworker と標準のマルチスレッド環境の主な違いは、メモリ リソースがメイン スレッドと共有されないことです。オブジェクトへの参照は、あるスレッドから別のスレッドに表示されません。スレッドはメッセージを交換することによって通信するため、イベント駆動型の設計パターンに従って、同期および同時メソッド呼び出しアルゴリズムを実装できます。
多くのフレームワークが存在し、スレッド間のプログラミングを構造化できます。その中には、同時プログラミングをサポートする OOP js フレームワークである OODK-JS https://github.com/GOMServices/oodk-js-oop-for-jsがあります。