34

Linux カーネルはプリエンプティブであり、ほとんどの Unix カーネルとは異なります。では、カーネルがプリエンプティブであるとは、実際にはどういう意味なのでしょうか?

いくつかの類推や例は、純粋な理論的説明よりも優れています。

1 を追加 -- 2018 年 12 月 7 日午前 11:00

プリエンプティブは、マルチタスクの 1 つのパラダイムにすぎません。Cooperative Multi-tasking のようなものもあります。それらを比較することで、より理解を深めることができます。

4

9 に答える 9

33

Prior to Linux kernel version 2.5.4, Linux Kernel was not preemptive which means a process running in kernel mode cannot be moved out of processor until it itself leaves the processor or it starts waiting for some input output operation to get complete.

Generally a process in user mode can enter into kernel mode using system calls. Previously when the kernel was non-preemptive, a lower priority process could priority invert a higher priority process by denying it access to the processor by repeatedly calling system calls and remaining in the kernel mode. Even if the lower priority process' timeslice expired, it would continue running until it completed its work in the kernel or voluntarily relinquished control. If the higher priority process waiting to run is a text editor in which the user is typing or an MP3 player ready to refill its audio buffer, the result is poor interactive performance. This way non-preemptive kernel was a major drawback at that time.

于 2011-03-12T16:12:03.830 に答える
27

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

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

Older Linux kernels would never allow preemption of a task while it was busy running kernel code. (Note that I/O operations always voluntarily re-schedule. I'm talking about a case where the kernel code has some CPU-intensive operation like sorting a list.)

If the system allows that task to be preempted while it is running kernel code, then we have what is called a "preemptive kernel." Such a system is immune to unpredictable delays that can be encountered during syscalls, so it might be better suited for embedded or real-time tasks.

For example, if on a particular CPU there are two tasks available, and one takes a syscall that takes 5ms to complete, and the other is an MP3 player application that needs to feed the audio pipe every 2ms, you might hear stuttering audio.

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

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

于 2011-03-12T17:18:09.097 に答える
10

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

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

シングル プロセッサ システムでは、これによって多くの問題が生じることはありません。

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

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

于 2011-03-12T15:54:31.553 に答える
5

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

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

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

于 2011-03-12T15:54:32.103 に答える
4

Linux カーネルはモノリシックであり、実行中のすべてのプロセスに順番に少しのコンピューティング タイムスパンを与えます。これは、プロセス (プログラムなど) が同時に実行されるのではなく、ロジックを実行するために一定の期間が定期的に与えられることを意味します。主な問題は、一部のロジックが終了するのに時間がかかり、カーネルが次のプロセスのための時間を確保できないことです。これにより、システムの「遅延」が発生します。

プリエンティブ カーネルには、コンテキストを切り替える機能があります。これは、「ハングしている」プロセスが終了していなくても停止し、期待どおりに次のプロセスに計算時間を与えることができることを意味します。「ハングしている」プロセスは、その時が来ても問題なく実行され続けます。

実際には、これは、カーネルがタスクをリアルタイムで実行できることを意味します。これは、オーディオの録音と編集にとって特に興味深いものです。

ubuntu スタジオ ディストリビューションには、プリエンプティブ カーネルと、オーディオとビデオの編集専用の高品質のフリー ソフトウェアが多数パッケージ化されています。

于 2011-03-12T15:55:15.803 に答える
3

これは、オペレーティングシステムスケジューラが実行中のプロセスの実行を自由に一時停止して、CPUを別のプロセスにいつでも提供できることを意味します。これを行う通常の方法は、CPUを待機している各プロセスにCPU時間の「クォンタム」の実行を与えることです。有効期限が切れると、スケジューラーは制御を取り戻し(実行中のプロセスはこれを回避できません)、別のクォンタムを別のプロセスに渡します。

この方法は、プロセスが中断されることなく必要な時間だけCPUを保持し、他のアプリケーションを実行させるために、ある種の「yield」関数を明示的に呼び出さなければならない協調マルチタスクとよく比較されます。当然のことながら、システムがスタックしているような感覚を与えることを避けるために、正常に動作するアプリケーションはCPUを頻繁に生成します。それでも、アプリケーションにバグがある場合(たとえば、yield呼び出しのない無限ループ)、CPUは障害のあるプログラムによって完全に保持されているため、システム全体がハングします。

最近のほとんどすべてのデスクトップOSは、プリエンプティブマルチタスクを使用しています。これは、リソースの点でより高価であっても、一般的に安定しています(OSは常に制御されているため、単一の障害のあるアプリがシステム全体をハングアップさせるのはより困難です)。一方、リソースが不足していて、アプリケーションが正常に動作することが期待される場合は、協調マルチタスクが使用されます。Windows3は協調マルチタスクOSでした。最近の例としては、オープンソースのPMPファームウェアの代替品であるRockBoxがあります。

于 2011-03-12T16:05:50.200 に答える
0

2.6からプリエンプティブになったと思います。プリエンプティブとは、新しいプロセスを実行する準備ができたときに、CPUが新しいプロセスに割り当てられることを意味します。実行中のプロセスが協調してCPUを放棄する必要はありません。

于 2011-03-12T15:53:40.440 に答える