GNU/Linux >> Linux の 問題 >  >> Linux

Linux カーネルがプリエンプティブであるとはどういう意味ですか?

従来の UNIX カーネルには単一のロックがあり、カーネル コードの実行中にスレッドによって保持されていました。したがって、他のカーネル コードはそのスレッドを中断できませんでした。

これにより、あるスレッドがカーネル リソースを使用している間、他のスレッドが使用していないことがわかっていたため、カーネルの設計が容易になりました。したがって、異なるスレッドが互いの作業を台無しにすることはありません。

シングル プロセッサ システムでは、これはそれほど多くの問題を引き起こしません。

ただし、マルチプロセッサ システムでは、異なるプロセッサまたはコア上の複数のスレッドがすべて同時にカーネル コードを実行しようとする状況が発生する可能性があります。これは、ワークロードの種類によっては、多数のプロセッサを使用できることを意味しますが、すべてのプロセッサはほとんどの時間を互いの待機に費やします。

Linux 2.6 では、カーネル リソースははるかに小さな単位に分割され、個々のロックによって保護されました。また、対応するリソースが使用されている間のみロックが保持されるようにカーネル コードが見直されました。そのため、異なるプロセッサが同じリソース (ハードウェア リソースなど) にアクセスしたい場合は、互いに待機するだけで済みます。


Linux カーネル バージョン 2.5.4 より前では、Linux カーネルはプリエンプティブではありませんでした。つまり、カーネル モードで実行されているプロセスは、それ自体がプロセッサを離れるか、なんらかの入出力操作が完了するのを待ち始めるまで、プロセッサの外に移動できません。

通常、ユーザー モードのプロセスは、システム コールを使用してカーネル モードに入ることができます。以前は、カーネルが非プリエンプティブであった場合、優先度の低いプロセスは、システム コールを繰り返し呼び出してカーネル モードのままにすることでプロセッサへのアクセスを拒否することで、優先度の高いプロセスの優先順位を逆転させることができました。優先度の低いプロセスのタイムスライスが期限切れになった場合でも、カーネルでの作業が完了するか、自発的に制御を放棄するまで実行を続けます。実行を待機している優先度の高いプロセスが、ユーザーが入力しているテキスト エディターまたはオーディオ バッファーを補充する準備ができている MP3 プレーヤーである場合、インタラクティブなパフォーマンスが低下します。このように非プリエンプティブ カーネルは当時の大きな欠点でした。


プリエンプティブ マルチタスキングの単純なビューを想像してみてください。 2 つのユーザー タスクがあり、どちらも I/O を使用したり、カーネル呼び出しを実行したりせずに常に実行されています。これら 2 つのタスクは、マルチタスク オペレーティング システムで実行できるようにするために特別なことを行う必要はありません。カーネルは通常、タイマー割り込みに基づいて、1 つのタスクを一時停止して別のタスクを実行できるようにすると単純に判断します。問題のタスクは、何かが起こったことをまったく認識していません。

ただし、ほとんどのタスクは、システムコールを介してカーネルの要求を時折行います。これが発生すると、同じユーザー コンテキストが存在しますが、CPU はそのタスクに代わってカーネル コードを実行しています。

古い Linux カーネルでは、カーネル コードの実行中はタスクのプリエンプションが許可されませんでした。 (I/O 操作は常に自発的に再スケジュールされることに注意してください。これは、カーネル コードに、リストの並べ替えなどの CPU を集中的に使用する操作がある場合のことです。)

システムがカーネル コードの実行中にそのタスクのプリエンプトを許可する場合、 次に、「プリエンプティブ カーネル」と呼ばれるものがあります。このようなシステムは、syscall 中に発生する可能性のある予測不可能な遅延の影響を受けないため、組み込みタスクやリアルタイム タスクにより適している可能性があります。

たとえば、特定の CPU で 2 つのタスクが利用可能で、1 つが完了までに 5 ミリ秒かかる syscall を実行し、もう 1 つが 2 ミリ秒ごとにオーディオ パイプにフィードする必要がある MP3 プレーヤー アプリケーションである場合、音声が途切れる可能性があります。 /P>

プリエンプションに反対する議論は、タスク コンテキストで呼び出される可能性のあるすべてのカーネル コードがプリエンプションに耐えられなければならないということです。そのプロセッサで他のタスクを実行できるようにします。 (最近のマルチプロセッサ システムでは、すべてのカーネル コードは再入可能でなければならないため、例外ではなくルールになっているため、今日ではそのような議論は適切ではありません。)さらに、悪いシステム コールを改善することで同じ目標を達成できる場合は、おそらくプリエンプションは不要です。

妥協点は CONFIG_PREEMPT_VOLUNTARY です。これは、カーネル内の特定のポイントでタスク切り替えを許可しますが、どこでも許可するわけではありません。カーネル コードが行き詰まる可能性のある場所が少数しかない場合、これは、複雑さを管理しやすく保ちながらレイテンシを削減する安価な方法です。


プリエンプションにより、カーネルは並列処理の印象を与えることができます。プロセッサは 1 つしかありませんが (10 年前としましょう)、すべてのプロセスが同時に実行されているように感じます。これは、カーネルが 1 つのプロセスからの実行をプリエンプション (つまり、実行を除外) して、次のプロセスに実行を渡すためです (優先度に応じて)。

編集 プリエンプティブ カーネルは、プロセスが手を返すのを待ちません。 (つまり、syscall 中)、プロセスが大量のデータを計算し、どのような種類の yield も呼び出さない場合 関数を実行すると、他のプロセスは呼び出しを実行できなくなります。このようなシステムは協調的であると言われています 実行時間の公平性を確保するためにプロセスの協力を求めるため

編集 2 プリエンプションの主な目的は、複数のタスク間のシステムの反応性を改善することです。これはエンドユーザーにとっては良いことですが、サーバーは最高のスループットを達成したいので、必要ありません。 Linux カーネル構成)

  • プリエンプティブル カーネル (低レイテンシ デスクトップ)
  • 自発的なカーネル プリエンプション (デスクトップ)
  • 強制プリエンプションなし (サーバー)

Linux
  1. 「–」(二点鎖線)とはどういう意味ですか?

  2. Linuxカーネルコードで__initはどういう意味ですか?

  3. Linux カーネル コードでの EXPORT_SYMBOL の意味は何ですか?

  1. Linux の 32 ビット コードでは、int 0x80 と syscall のどちらが優れていますか?

  2. Linux カーネルモジュールのコーディング方法は?

  3. Linuxコマンドの最後の&はどういう意味ですか?

  1. この Linux コマンドの - はどういう意味ですか?

  2. [[ $? -ne 0 ]]; .ksh の意味

  3. Linux で eth0 インターフェース名は何を意味しますか?