コンピュータプログラミングにおいて、グリーンスレッドとは、基盤となるオペレーティングシステム(OS)ではなく、ランタイムライブラリまたは仮想マシン(VM)によってスケジュールされるスレッドのことです。グリーンスレッドは、OS のネイティブ機能に依存せずにマルチスレッド環境をエミュレートし、カーネル空間ではなくユーザー空間で管理されるため、ネイティブスレッドサポートのない環境でも動作します。[1]
語源
グリーンスレッドは、 Javaプログラミング言語のオリジナルのスレッドライブラリの名前を指します(バージョン1.1でリリースされ、バージョン1.3でグリーンスレッドはネイティブスレッドに置き換えられました)。これは、サンマイクロシステムズのグリーンチームによって設計されました。[2]
歴史
グリーン スレッドは、1997 年から 2000 年にかけて Java で短期間使用できました。
グリーン スレッドは、協調的な同時実行を通じて単一のオペレーティング システム スレッドを共有するため、オペレーティング システム スレッドのような並列処理によるパフォーマンスの向上は実現できません。コルーチンとグリーン スレッドの主な利点は、実装が簡単なことです。
パフォーマンス
マルチコアプロセッサでは、ネイティブスレッド実装は複数のプロセッサに作業を自動的に割り当てることができますが、グリーンスレッド実装では通常それができません。[1] [3]グリーンスレッドは、一部のVMではるかに高速に起動できます。ただし、ユニプロセッサコンピュータでは、最も効率的なモデルはまだ明確に決定されていません。
Linuxカーネルバージョン2.2(1999年リリース)を実行しているコンピュータのベンチマークでは、次の結果が出ています。 [4]
- グリーン スレッドは、スレッドのアクティブ化と同期に関して Linux ネイティブ スレッドよりも大幅に優れています。
- Linux ネイティブ スレッドは、入出力(I/O) およびコンテキスト切り替え操作のパフォーマンスがわずかに優れています。
グリーンスレッドがブロッキングシステムコールを実行すると、そのスレッドがブロックされるだけでなく、プロセス内のすべてのスレッドがブロックされます。[5]この問題を回避するには、グリーンスレッドは非ブロッキングI/Oまたは非同期I/O操作を使用する必要がありますが、グリーンスレッドを実装する仮想マシンが各I/O操作に対して特定のI/Oプロセス(ユーザーには非表示)を生成すると、ユーザー側の複雑さが軽減されます。[要出典]
ネイティブ スレッドの使用を可能にし、スレッドのアクティブ化と同期のオーバーヘッドを削減するメカニズムもあります。
- スレッドプールは限られた数のスレッドを再利用することで、新しいスレッドを生成するコストを削減します。[6]
- 仮想マシンとネイティブスレッドを使用する言語では、エスケープ解析を使用して、不要なコードブロックの同期を回避することができます。[7]
Java仮想マシンのグリーンスレッド
Java 1.1では、グリーンスレッドはJava仮想マシン(JVM)で使用される唯一のスレッドモデルでした[8](少なくともSolarisでは)。グリーンスレッドはネイティブスレッドに比べていくつかの制限があるため、その後のJavaバージョンではネイティブスレッドに置き換えられました[9] [10] 。
例外はSquawk 仮想マシンです。これは、低電力デバイス用のオペレーティング システムと Java 仮想マシンを組み合わせたものです。グリーン スレッドを使用して、ネイティブ コードの使用を最小限に抑え、その分離の移行をサポートします。
Kilim [11] [12]とQuasar [13] [14]は、Javaコンパイラによって生成されたJavaバイトコードを 変更することで、JVMの新しいバージョンにグリーンスレッドを実装するオープンソースプロジェクトです(QuasarはKotlinとClojureもサポートしています)。
他の言語でのグリーンスレッド
ネイティブ スレッドの代わりにグリーン スレッドと同等のものを実装する プログラミング言語は他にもいくつかあります。例:
- Chicken Schemeはファーストクラスの継続に基づく軽量なユーザーレベルスレッドを使用する[15]
- コモンリスプ[16]
- CPythonはバージョン3.4以降、ネイティブでasyncioをサポートしており、greenlet、eventlet、gevent、PyPyなどの代替実装も存在する[17]
- クリスタルは繊維を提供する[18]
- Dは非同期I/Oに使用されるファイバーを提供する[19]
- Dyalog APLではスレッドと呼んでいる[20]
- アーラン[21]
- Goはゴルーチンと呼ばれるものを実装している[22]
- ハスケル[22]
- Julia はタスクにグリーン スレッドを使用します。
- リンボ[23]
- Lua は並行処理にコルーチンを使用します。Lua 5.2 では、関数 lua_yieldk、lua_callk、および lua_pcallk を通じて、真の C コルーチン セマンティクスも提供されます。CoCo 拡張機能により、Lua 5.1 で真の C コルーチン セマンティクスが可能になります。
- Nimは非同期I/Oとコルーチンを提供する
- OCaml はバージョン5.0以降、Domainslib.Taskモジュールを通じてグリーンスレッドをサポートしています。
- オッカムは、連続したプロセスの通信に由来するため、スレッドではなくプロセスという用語を好む。
- Perlはコルーチンを通じてグリーンスレッドをサポートします
- PHPはファイバーとコルーチンを通じてグリーンスレッドをサポートします
- Rubyバージョン1.9以前[24]
- ラケット(ネイティブスレッドはPlaces [25]からも入手可能)
- Rustはシステムスレッドをネイティブにサポートしており[26]、Tokioなどのサードパーティライブラリを通じて非同期I/Oをサポートしています。
- SML/NJの同時実行 MLの実装
- Smalltalk (ほとんどの方言: Squeak、VisualWorks、GNU Smalltalkなど)
- スタックレスPythonは、マイクロスレッド(タスクレットと呼ばれる)を通じてプリエンプティブマルチタスクまたは協調マルチタスクのいずれかをサポートします。[27]
- Tclにはコルーチンとイベントループがある[28]
Erlang仮想マシンには、グリーン プロセスと呼ばれるものがあります。これはオペレーティング システムのプロセスに似ていますが (スレッドのように状態を共有しません)、Erlang ランタイム システム (erts) 内に実装されています。これらはグリーン スレッドと呼ばれることもありますが、標準のグリーン スレッドとは大きな違いがあります[説明が必要]。[引用が必要]
GHC Haskell の場合、設定可能なタイムアウト後の最初の割り当て時にコンテキスト スイッチが発生します。GHC スレッドは、その存続期間中に 1 つ以上の OS スレッドで実行される可能性もあります (GHC スレッドと OS スレッドの間には多対多の関係があります)。これにより、対称型マルチプロセッシングマシンでの並列処理が可能になりますが、利用可能なコア数で実行するために必要なコストよりも高い OS スレッドは作成されません。[要出典]
ほとんどの Smalltalk 仮想マシンは評価ステップをカウントしません。ただし、仮想マシンは外部シグナル (タイマーの期限切れや I/O が使用可能になるなど) に基づいて実行中のスレッドをプリエンプトできます。通常はラウンドロビン スケジューリングが使用され、定期的に起動する優先度の高いプロセスがタイムシェアリング プリエンプションを効果的に実装します。
[
[(遅延時間 : 50ミリ秒)待機]繰り返し
] forkAt: プロセッサの 高IOPriority
QKS Smalltalk などの他の実装は常にタイムシェアリングです。ほとんどのグリーン スレッド実装とは異なり、QKS は優先度の逆転の防止もサポートしています。
Java仮想マシンの仮想スレッドとの違い
仮想スレッドはJava 19 [29]でプレビュー機能として導入され、Java 21 [30]で安定化されました。仮想スレッドとグリーンスレッドの重要な違いは次のとおりです。
- 仮想スレッドは、既存の (非仮想) プラットフォーム スレッドおよびスレッド プールと共存します。
- 仮想スレッドは抽象化を保護します。
- グリーン スレッドとは異なり、仮想スレッドでスリープしても、基礎となるキャリア スレッドはブロックされません。
- スレッドローカル変数の操作は重視されておらず、より軽量な代替としてスコープ付きの値が提案されています。[31]
- 仮想スレッドは、特殊
jdk.internal.vm.Continuationクラスの JVM サポートを利用することで、簡単に中断および再開できます。 - 仮想スレッドは、可能な場合はキャリア スレッドから透過的にアンマウントすることでブロッキング呼び出しを処理し、そうでない場合はプラットフォーム スレッドの数を増やすことで補正します。
参照
参考文献
- ^ ab Sintes, Tony (2001 年 4 月 13 日). 「Four for the years」. JavaWorld . 2020 年 7 月 15 日にオリジナルからアーカイブ。2020年 7 月 14 日に取得。グリーン
スレッド (JVM によって提供されるスレッド) はユーザー レベルで実行されます。つまり、JVM 自体がスレッドを作成してスケジュールします。したがって、オペレーティング システム カーネルはスレッドを作成またはスケジュールしません。代わりに、基盤となる OS は JVM を 1 つのスレッドとしてのみ認識します。グリーン スレッドは、いくつかの理由で非効率的です。まず、グリーン スレッドはマルチプロセッサ システムを活用できません (...) したがって、JVM スレッドは、単一のプロセッサ内で実行される単一の JVM スレッド内で実行されることになります。
{{cite web}}: CS1 maint: bot: original URL status unknown (link) - ^ 「Java テクノロジー: 初期の頃」java.sun.com 2014 年 12 月 22 日。2008 年 5 月 30 日時点のオリジナルよりアーカイブ。
- ^ 「「グリーン」スレッドと「ネイティブ」スレッドの違いは何ですか?」jguru.com 2000-09-06 2009-06-01取得マルチ
CPU マシンでは、ネイティブ スレッドは、異なるスレッドを異なる CPU に割り当てることで、複数のスレッドを同時に実行できます。グリーン スレッドは、1 つの CPU でのみ実行されます。
- ^ 「組み込みアプリケーション向け Java スレッドの比較パフォーマンス評価: Linux スレッドとグリーン スレッド」CiteSeerX 10.1.1.8.9238。
- ^ Stallings, William (2008).オペレーティングシステムの内部および設計原則. ニュージャージー: Prentice Hall. p. 171. ISBN 9780136006329。
- ^ Sieger, Nick (2011-07-22). 「JRuby の並行性」。Engine Yard。2014-01-30 にオリジナルからアーカイブ。2013-01-26に取得。
大量の電子メールを扱うシステムでは、この単純なアプローチはうまく機能しない可能性があります。ネイティブ スレッドはグリーン スレッドよりも初期化コストとメモリ オーバーヘッドが大きいため、JRuby は通常 10,000 を超えるスレッドをサポートできません。この問題を回避するには、スレッド プールを使用します。
- ^ Goetz, Brian (2005-10-18). 「Java の理論と実践: Mustang での同期の最適化」IBM . 2013-01-26閲覧。
- ^ 「Solaris 環境における Java スレッド - 以前のリリース」。Oracle Corporation。2013年 1 月 26 日取得。
その結果、いくつかの問題が発生しました。Java アプリケーションは Solaris 環境の既存の MT アプリケーションと相互運用できない、Java スレッドはマルチプロセッサ上で並列実行できない、マルチプロセッサ Java アプリケーションは単一プロセッサでもマルチプロセッサでも、より高速なアプリケーションのために真の OS 同時実行性を利用することができない。アプリケーションのパフォーマンスを大幅に向上させるために、Solaris 2.6 プラットフォームでは、グリーン スレッド ライブラリが Java 用のネイティブ Solaris スレッドに置き換えられました。これは、Solaris 7 および Solaris 8 プラットフォームにも引き継がれています。
- ^ 「スレッド: グリーンかネイティブか」。SCO グループ。2013 年 1 月 26 日取得。MP
マシンでネイティブ スレッドを使用することで得られるパフォーマンス上の利点は劇的なものになる可能性があります。たとえば、Java スレッドが互いに独立して処理を実行する人工的なベンチマークを使用すると、4 CPU MP マシンで全体的な速度が 3 倍向上する可能性があります。
- ^ 「スレッド: グリーンかネイティブか」 codestyle.org。2013 年 1 月 16 日にオリジナルからアーカイブ。2013 年 1 月 26 日に取得。JVM
がスレッドの状態を追跡し、それらの間でスワップするには、かなりの処理オーバーヘッドがかかるため、グリーン スレッド モードは非推奨となり、最近の Java 実装から削除されました。
- ^ "kilim". GitHub . 2016年6月9日閲覧。
- ^ “Kilim”. www.malhar.net . 2016年6月9日閲覧。
- ^ 「Quasar Code on GitHub」。GitHub。
- ^ “Parallel Universe”。2015年12月22日時点のオリジナルよりアーカイブ。2015年12月6日閲覧。
- ^ 「Chicken Scheme」 。 2017年11月5日閲覧。
- ^ "thezerobit/green-threads". GitHub . 2016年4月8日閲覧。
- ^ 「アプリケーションレベルのスタックレス機能 - PyPy 4.0.0 ドキュメント」 。2015年12 月 6 日閲覧。
- ^ 「Concurrency: GitBook」. crystal-lang.org . 2018年4月3日閲覧。
- ^ 「Fibers - Dlang Tour」。tour.dlang.org 。2022年5月2日閲覧。
- ^ 「スレッド: 概要」。Dyalog APL 17.0 ヘルプ。2018 年 12 月 14 日取得。
スレッド
は、
APL ワークスペース内の実行のストランドです。
- ^ @joeerl (2018 年 6 月 23 日)。「Erlang プロセスは、グリーン スレッドのように Erlang VM でエミュレートされます。多くの問題が簡素化されるので気に入っています…」(ツイート) – Twitter経由。
- ^ ab "Go and Dogma". research!rsc . 2017-01-14取得。
たとえば、Go と Haskell はどちらも何らかの「グリーン スレッド」を必要とするため、予想以上に多くの共通の実行時課題があります。
- ^ 「Limboプログラミング言語」www.vitanuova.com . 2019年4月1日閲覧。
- ^ 「MRI Ruby インタープリターでのマルチスレッド | BugFactory」 。2024年 6 月 18 日閲覧。
- ^ 「Racket Places」 。2011年 10 月 13 日取得。Places
を使用すると、複数のプロセッサ、コア、またはハードウェア スレッドを備えたマシンを活用する並列プログラムの開発が可能になります。Places は、実質的に Racket 仮想マシンの個別のインスタンスである並列タスクです。
- ^ 「スレッドを使用してコードを同時に実行する - Rust プログラミング言語」。doc.rust-lang.org。2021年 9 月 24 日閲覧。
- ^ 「Stackless.com: Stackless について」。2012 年 2 月 27 日にオリジナルからアーカイブ。2008 年 8 月 27 日に取得。
ラウンドロビン スケジューラが組み込まれています。これを使用して、タスクレットを協調的またはプリエンプティブにスケジュールできます。
- ^ 「Tcl イベント ループ」 。2015年12 月 6 日閲覧。
- ^ 「JEP 425: 仮想スレッド (プレビュー)」。2024年1月25日閲覧。
- ^ 「JEP 444: 仮想スレッド」。2024年1月25日閲覧。
- ^ 「JEP 464: スコープ付き値(第2プレビュー)」。2024年1月25日閲覧。
外部リンク
- 「Four for the years」、グリーン スレッドに関するJavaWorld の記事
- Java スレッドのグリーン スレッドに関する FAQ
