糸と繊維の違いは何ですか?


187

糸と繊維の違いは何ですか?ルビーの繊維について聞いたことがありますが、他の言語でも利用できると聞いたことがあります。糸と繊維の違いを簡単に説明してもらえますか。

回答:


163

最も単純な用語では、スレッドは一般にプリエンプティブであると見なされます(ただし、オペレーティングシステムによっては、これが常に当てはまるとは限りません)。ファイバーは軽量の協調スレッドであると見なされます。どちらもアプリケーションの個別の実行パスです。

スレッドあり:現在の実行パスはいつでも中断またはプリエンプトされる可能性があります(注:このステートメントは一般化であり、OS /スレッド化パッケージなどによっては常に当てはまるとは限りません)。つまり、スレッドの場合、データのチャンクの更新中に1つのスレッドが停止し、データの整合性が不良または不完全な状態になるため、データの整合性が大きな問題になります。これは、オペレーティングシステムが複数のCPUとCPUコアを利用して、同時に複数のスレッドを実行し、開発者に任せてデータアクセスを保護できることも意味します。

ファイバーあり:現在の実行パスは、ファイバーが実行を生成したときにのみ中断されます(上記と同じメモ)。つまり、ファイバーは常に明確に定義された場所で開始および停止するため、データの整合性はそれほど問題になりません。また、ファイバーはユーザー空間で管理されることが多いため、高価なコンテキストスイッチやCPU状態の変更を行う必要がなく、ファイバーを次のファイバーに非常に効率的に変更できます。一方、2つのファイバーを同時に実行することはできないため、ファイバーのみを使用しても、複数のCPUや複数のCPUコアを利用することはできません。


7
複数のスレッドを使用してファイバーを並列に実行する方法はありますか?
バラデ

2
@ジェイソン、〜「ファイバーを使用すると、現在の実行パスはファイバーが実行を開始したときにのみ中断される」と述べ、「ファイバーは常に明確に定義された場所で開始および停止するため、データの整合性はそれほど問題ではありません」、という意味ですか?変数を共有する場合、「ロックメカニズム」と揮発性変数を使用する必要はありませんか?それとも、私たちはまだそれらのことをする必要があるということですか?
パセリエ2015年

@バラデそれは面白い質問です、あなたは答えを見つけましたか?
Mayur

57

スレッドはプリエンプティブスケジューリングを使用ますが、ファイバーは協調スケジューリングを使用ます。

スレッドを使用すると、制御フローがいつでも中断され、別のスレッドが引き継ぐ可能性があります。複数のプロセッサを使用すると、複数のスレッドをすべて同時に実行できます(同時マルチスレッド、またはSMT)。その結果、同時データアクセスに非常に注意し、ミューテックス、セマフォ、条件変数などでデータを保護する必要があります。多くの場合、正しく理解するのは非常に困難です。

ファイバーを使用すると、通常はのような名前の関数呼び出しを使用して、制御が指示したときにのみスイッチが切り替わりますyield()。これにより、データ構造やミューテックスの原子性について心配する必要がないため、同時データアクセスが容易になります。譲歩しない限り、プリエンプトされたり、作業中のデータを別のファイバーが読み取ったり変更したりする危険はありません。ただし、結果として、ファイバーが無限ループに陥ると、他のファイバーが実行できなくなります。

また、糸と繊維を混ぜることもできます。これは、両方が直面する問題を引き起こします。推奨されていませんが、慎重に行うと、正しいことになる場合があります。


3
無限ループは修正が必要なバグに過ぎないと思います。無限ループがある場合、スレッドはかなりあいまいな利点しか持っていません。関連するバグのない概念は、ユーザーがキャンセルしたい可能性のある長期実行プロセスがある場合です。この場合、スレッドとファイバーのどちらを使用する場合でも、長期実行プロセスは協調的である必要があります。そのスレッドを強制終了するだけでデータ構造の一部がめちゃくちゃになる可能性があるため、たとえば、長期実行プロセスのスレッドが定期的にチェックすることです中断された場合。これは、ファイバーが定期的に降伏することとそれほど変わりません。
Evgeni Sergeev

43

Win32では、ファイバーはユーザー管理のスレッドの一種です。ファイバーには独自のスタックや独自の命令ポインターなどがありますが、ファイバーはOSによってスケジュールされていません。SwitchToFiberを明示的に呼び出す必要があります。対照的に、スレッドはオペレーティングシステムによって事前にスケジュールされます。つまり、ファイバーとは、真のOSスレッドではなく、アプリケーション/ランタイムレベルで管理されるスレッドです。

その結果、ファイバーは安価になり、アプリケーションはスケジューリングをより細かく制御できるようになります。これは、アプリが多数の同時タスクを作成する場合や、実行時に厳密に最適化する場合に重要になります。たとえば、データベースサーバーは、スレッドではなくファイバーの使用を選択する場合があります。

(同じ用語には他の用法があるかもしれません。注記したように、これはWin32の定義です。)


37

まず、プロセスとスレッドの違いに関するこの説明を背景資料として読むことをお勧めします。

それを読んだら、それはかなり簡単です。スレッドは、カーネル、ユーザー空間のいずれかに実装することも、2つを混在させることもできます。ファイバーは基本的にユーザー空間で実装されるスレッドです。

  • 一般的にスレッドと呼ばれるものは、カーネルに実装された実行のスレッドであり、カーネルスレッドと呼ばれます。カーネルスレッドのスケジューリングは、カーネルによって排他的に処理されますが、カーネルスレッドは、必要に応じてスリープすることにより、自発的にCPUを解放できます。カーネルスレッドには、ブロッキングI / Oを使用して、カーネルがスケジューリングを心配できるという利点があります。主な欠点は、カーネルへのトラップが必要なため、スレッドの切り替えが比較的遅いことです。
  • ファイバーは、ユーザースペーススレッドであり、そのスケジューリングは、単一のプロセスの下で1つ以上のカーネルスレッドによってユーザースペースで処理されます。これにより、ファイバーの切り替えが非常に高速になります。単一のカーネルスレッドのコンテキストで特定の共有データセットにアクセスするすべてのファイバーをグループ化し、それらのスケジューリングを単一のカーネルスレッドで処理する場合、ファイバーは実質的にシリアルで実行され、完了しているため、同期の問題を排除できます。彼らのスケジューリングを制御します。単一のカーネルスレッドの下で関連するファイバーをグループ化することは重要です。それらが実行されているカーネルスレッドはカーネルによってプリエンプトされる可能性があるためです。この点は、他の多くの回答では明らかにされていません。また、ファイバーでブロッキングI / Oを使用する場合、カーネルスレッド全体は、そのカーネルスレッドの一部であるすべてのファイバーを含むブロックの一部です。

現代のオペレーティングシステムのセクション11.4「Windows Vistaのプロセスとスレッド」で、タネンバウムは次のようにコメントしています。

ファイバーは協調的にスケジュールされますが、ファイバーをスケジュールする複数のスレッドがある場合、ファイバーが互いに干渉しないようにするために、多くの注意深い同期が必要です。スレッドとファイバー間の相互作用を簡素化するには、多くの場合、スレッドを実行するプロセッサーの数と同じ数のスレッドのみを作成し、使用可能なプロセッサーの個別のセットまたは1つのプロセッサーでのみ実行するようにスレッドをアフィニティ化すると便利です。次に、各スレッドはファイバーの特定のサブセットを実行し、同期を簡素化するスレッドとファイバー間の1対多の関係を確立します。それでも、繊維にはまだ多くの問題があります。ほとんどのWin32ライブラリはファイバーを完全に認識していないため、スレッドのようにファイバーを使用しようとするアプリケーションでは、さまざまなエラーが発生します。カーネルはファイバーを認識していないため、ファイバーがカーネルに入ると、実行中のスレッドがブロックし、カーネルがプロセッサ上の任意のスレッドをスケジュールして、他のファイバーを実行できないようにします。これらの理由により、ファイバーが提供する機能を明示的に必要とする他のシステムからコードを移植する場合を除いて、ファイバーが使用されることはほとんどありません。


4
これが最も完全な答えです。
Bernard

12

スレッドとファイバーに加えて、Windows 7ではユーザーモードスケジューリングが導入されています

ユーザーモードスケジューリング(UMS)は、アプリケーションが独自のスレッドをスケジュールするために使用できる軽量のメカニズムです。アプリケーションは、システムスケジューラを使用せずにユーザーモードでUMSスレッドを切り替え、UMSスレッドがカーネルでブロックされた場合にプロセッサの制御を取り戻すことができます。UMSスレッドは、各UMSスレッドが単一のスレッドのスレッドコンテキストを共有するのではなく、独自のスレッドコンテキストを持つという点でファイバーとは異なります。ユーザーモードでスレッドを切り替える機能により、UMSはスレッドプールよりも効率的で、システムコールをほとんど必要としない多数の短期間の作業項目を管理できます。

スレッド、ファイバー、UMSの詳細については、Dave Probert:Inside Windows 7-User Mode Scheduler(UMS)をご覧ください。


7

スレッドはOSによってスケジュールされます(プリエンプティブ)。スレッドはOSによっていつでも停止または再開できますが、ファイバーは多かれ少なかれ自分自身を管理し(協調的)、お互いに譲歩します。つまり、プログラマは、ファイバーがいつ処理を行うか、およびその処理が別のファイバーに切り替わるタイミングを制御します。


7

一般に、スレッドはカーネルに依存してスレッドを中断するので、スレッドまたは別のスレッドを実行できます(これはプリエンプティブマルチタスクとして知られています)。一方、ファイバーは、ファイバー自体が実行時間を放棄する協調マルチタスクを使用します。他の繊維が走る可能性があります。

私がおそらくやったよりもそれをよりよく説明するいくつかの便利なリンクは:


7

スレッドはもともと軽量プロセスとして作成されました。同様に、ファイバーは軽量のスレッドであり、(単純に)ファイバー自体に依存して、制御を実現することでお互いをスケジュールします。

次のステップは、命令を実行するたびに信号を送信する必要があるストランドになると思います(私の5歳の息子とは異なります:-)。昔は(今でも一部の組み込みプラットフォームでは)、すべてのスレッドはファイバーであり、プリエンプションはなく、スレッドを適切に動作させるように記述する必要がありました。


3

Win32ファイバーの定義は、実際にはSun Microsystemsで確立された「グリーンスレッド」の定義です。ある種のスレッド、つまりユーザーコード/スレッドライブラリ制御下のユーザー空間で実行されているスレッドでファイバーという用語を無駄にする必要はありません。

引数を明確にするために、次のコメントを見てください。

  • ハイパースレッディングを使用すると、マルチコアCPUは複数のスレッドを受け入れ、各コアに1つずつ分散できます。
  • スーパースカラーパイプラインCPUは、1つのスレッドを実行のために受け入れ、命令レベル並列処理(ILP)を使用してスレッドをより高速に実行します。1つのスレッドが、並列パイプラインで実行される並列ファイバーに分割されていると想定できます。
  • SMT CPUは、複数のスレッドを受け入れ、それらを命令ファイバーに分割して、パイプラインをより効率的に使用して、複数のパイプラインで並列実行できます。

プロセスは糸で作られ、糸は繊維で作られるべきだと仮定するべきです。そのロジックを念頭に置いて、他の種類のスレッドにファイバーを使用することは間違っています。


これは面白い。
JSON
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.