- 誰かがコルーチンとファイバーとは何かを説明できますか? 通常のルーチンやマルチタスク メカニズムと比較して、どのような問題を解決しますか。
- Linux が協調マルチタスクではなくプリエンプティブ マルチタスクを使用するのはなぜですか?
3 に答える
コルーチン、ファイバー、およびそれらの同類は、オペレーティング システムではなく、プログラミング言語のランタイムまたはライブラリによって管理される、スレッドのような実行コンテキストです。それらの用途は限られています。本当のスレッドが利用できるときに、そのようなハックを使用する正気の人は誰もいません。
Linux がプリエンプティブ マルチタスキングを使用していると言うのは簡単です。初期の Unix と同様に、初期の Linux はカーネル コードを実行するために協調マルチタスキングを使用していました。つまり、ユーザー空間の実行中はプロセスを横取りできますが、カーネル コードの実行中は横取りできません。カーネル コードの実行中、プロセスはスリープ状態の場合にのみ別のプロセスを実行するようにスケジュール解除されます。これは、スリープ状態のブロッキング関数を自発的に呼び出すことによって発生します。このアプローチにより、多くの競合状態が解消されるため、オペレーティング システムの内部構造が大幅に簡素化されます。少なくとも、プロセッサが 1 つしかない場合。カーネルコードを実行しているタスクは、割り込みについて心配するだけでよく、都合が悪いときはいつでも割り込みを一時的に無効にすることができます。
1990 年代半ばに実験的な Linux 1.3 カーネル シリーズでマルチ プロセッサのサポートが導入されたことで、その状況は変化し始めました。非プリエンプティブ カーネルは SMP をあまりサポートしません。これは、協調的なマルチタスクの保証を維持するために、一度に 1 つのプロセッサのみが入ることを許可する大きなロックをカーネルの周りに配置する必要があるためです。Linux では、これは BKL (ビッグ カーネル ロック) と呼ばれていました。
徐々に、BKL はカーネルへのすべてのエントリに適用されなくなり、よりきめ細かい SMP ロックに取って代わられました。カーネル空間内で複数のプロセッサを同時に実行すると、おかしな状況が発生します。ロック メカニズムによって保護された実際の同時実行が行われていますが、実行中のプロセッサを失うタスクがないという点で、カーネルは依然として協調的です。眠らない限り。
その時点で、プリエンプションを許可することは理にかなっています。そのため、これはオプションの形でカーネルに組み込まれました。このオプションCONFIG_PREEMPT
は長年実験的であり、すべてのアーキテクチャで一貫して適切に機能しない傾向があり、SMP と組み合わせて使用する傾向がありました。
カーネルがプリエンプティブルであることが望ましい理由は、イベントに対する応答時間が短縮されるなど、リアルタイム処理が向上するからです。プリエンプションにはリスクがありますが、ほとんどの問題は SMP を効率的にすることで解決されます。これにより、プリエンプションの採用基準が低くなる傾向があります。つまり、「なぜ、何のために」の問題ではなく、「なぜしないのか」という問題になります。
協調的なマルチタスカーは、低レイテンシーの I/O パフォーマンスを提供できないため、致命的な障害を負っています。
ドライバーが割り込みから戻ったときに、I/O 待機中のスレッドを準備/実行し、他の実行中のスレッドを先取りするプリエンプティブ マルチタスカーの機能により、GUI、ブラウザーなどを応答的に実行し、ビデオ/音楽プレーヤー、BitTorrent、 YouTube など、実際に動作することはまったくありません。
ファイバーやいわゆる「グリーン スレッド」などの協調タスクは、ニッチな分野で使用されることは間違いありませんが、汎用 OS ではほとんど役に立たないため、Linux や Windows (とにかく W95 以降) ) などなど。すべてプリエンプティブ マルチスレッド (または必要に応じてマルチプロセッシング) スケジューラを使用します。