プリエンプティブ カーネルでは、カーネル モードで実行されているプロセスを、カーネル機能の途中で別のプロセスに置き換えることができます。
これは、カーネル モードで実行されているプロセスにのみ適用されます。ユーザー モードでプロセスを実行している CPU は「アイドル」と見なされます。ユーザー モード プロセスがカーネルからサービスを要求したい場合、カーネルが処理できる例外を発行する必要があります。
例:
プロセス A
例外ハンドラを実行します, Process B
IRQ リクエストによって起動されると、カーネルはプロセス A
を置き換えます B
で (強制プロセス切り替え)。プロセス A
未完成のままです。スケジューラは、プロセス A
かどうかを後で決定します。 CPU 時間を取得するかどうか。
非プリエンプティブ カーネルでは、A
を処理します。 終了するまで、または自発的に他のプロセスが彼に割り込むことを許可することを決定するまで (計画されたプロセス切り替え)、すべてのプロセッサ時間を使用したことになります。
今日の Linux ベースのオペレーティング システムには、通常、完全にプリエンプティブなカーネルが含まれていません。中断することなく実行する必要がある重要な機能がまだ残っています。したがって、これを「選択的プリエンプティブ カーネル」と呼ぶことができると思います。
それとは別に、Linux カーネルを (ほぼ) 完全にプリエンプティブにするアプローチがあります。
- リアルタイム Linux Wiki
- LWN 記事
<ブロック引用>
プリエンプションとは -> より優先度の高いタスクを優先して、現在スケジュールされているタスクをプリエンプションまたは停止するオペレーティング システムの機能です。スケジューリングは、プロセスまたは I/O スケジューリングなどのいずれかですが、これらに限定されません。
Linux では、ユーザー空間プログラムは常にプリエンプティブルでした:カーネルはユーザー空間プログラムに割り込んで、通常のクロック ティックを使用して他のスレッドに切り替えます。そのため、カーネルは、ユーザー空間プログラムがプロセッサを明示的に解放するのを待ちません (これは協調マルチタスクの場合です)。これは、ユーザー空間プログラムの無限ループがシステムをブロックできないことを意味します。
ただし、2.6 カーネルまでは、カーネル自体はプリエンプティブルではありませんでした。1 つのスレッドがカーネルに入るとすぐに、別のスレッドを実行するためにプリエンプトできませんでした。そのため、カーネル プリエンプションは 2.6 カーネルで導入されており、CONFIG_PREEMPT オプションを使用して有効または無効にすることができます。 CONFIG_PREEMPT が有効になっている場合、コードがローカル割り込みを無効にしている場合を除き、カーネルコードはどこでもプリエンプトできます。コード内の無限ループは、システム全体をブロックできなくなりました。 CONFIG_PREEMPT が無効になっている場合、2.4 の動作が復元されます。
http://www.linuxquestions.org/questions/linux-general-1/pre-emptive-vs-non-pre-emptive-kernel-582437/から再引用およびフォーマット化