回答:
Linuxカーネルのコンテキストでは、人々がプリエンプションについて話すとき、彼らはしばしばカーネル自体を中断する能力を指します-基本的に、カーネルコードの実行中にタスクを切り替えます。これを可能にすることは非常に複雑です。これがおそらく、カーネルがプリエンプティブにされるのに長い時間がかかった主な理由です。
それは大きなカーネルロックで保護されているため、最初はほとんどのカーネルコードを中断できませんでした。そのロックは、ますます多くのカーネルコードから次第に削除され、並行してカーネルへの複数の同時呼び出しが可能になりました(SMPシステムが一般的になるにつれて、これはより重要になりました)。しかし、それでもカーネル自体をプリエンプティブにできませんでした。それはさらに開発を続け、PREEMPT_RT
最終的にメインラインカーネルにマージされたパッチセットで頂点に達しました(とにかくBKLをプリエンプトすることができました)。現在、カーネルは、スループットとレイテンシーの特性に応じて、多かれ少なかれプリエンプティブに設定できます。詳細については、関連するカーネル構成を参照してください。
カーネル構成の説明からわかるように、プリエンプションはスループットとレイテンシに影響し、同時性には影響しません。シングルCPUシステムでは、プリエンプションはイベントをより短い反応時間で処理できるため、依然として有用です。ただし、(カーネルはタスクの切り替えに時間を費やすため)スループットも低下します。プリエンプションにより、単一または複数のCPUシステム内の任意のCPUが、より迅速に別のタスクに切り替えることができます。マルチCPUシステムの制限要因はプリエンプションではなく、大きなロックなどのロックです。コードがロックを取得するたびに、別のCPUが同じアクションの実行を開始できないことを意味します。
プリエンプティブカーネルは、ビッグカーネルロックがないことを意味します。
Linuxには、最初の瞬間からプリエンプティブマルチタスクがありました(つまり、ユーザーコードはプリエンプティブでした)(LinusがFunet ftpサーバーにアップロードした非常に最初のLinux 0.0.1は、すでにプリエンプティブマルチタスクでした)。たとえば、複数の圧縮またはコンパイルプロセスを実行した場合、それらは最初の瞬間から並行して実行されました。
-当時-広く使用されているWin31に反して。Win31では、タスクが「カーネル」からCPUを取得した場合、デフォルトでOS(または他のタスク)に制御を戻すタイミングを決定するのはその責任でした。プロセスがこの機能を特別にサポートしていない場合(追加のプログラミング作業が必要)、実行中に他のすべてのタスクが中断されました。Win31に統合されたほとんどの基本的なアプリでもそのように機能しました。
プリエンプティブマルチタスクとは、タスクが必要に応じてCPUを割り当てる方法がないことを意味します。代わりに、タイムスロットが期限切れになると、カーネルはCPUをそれらから解放します。したがって、プリエンプティブオペレーティングシステムでは、不適切に記述されたプロセスまたは機能が不十分なプロセスがOSをフリーズしたり、他のプロセスの実行を回避したりすることはできません。Linuxは常にユーザー空間プロセスを先取りしていました。
ビッグカーネルロックとは、場合によっては、カーネルスペース内にロックが存在し、他のプロセスが保護されたコードを実行できないことを意味します。たとえば、複数のファイルシステムを同時にマウントすることはできません。複数のマウントコマンドを指定した場合、Big Kernel Lockを割り当てるためにマウントする必要があるため、それらは引き続き連続して実行されました。
カーネルをプリエンプティブにするには、この大きなカーネルロックを削除する必要がありました。つまり、マウントとその他のタスクを同時に実行できるようにしました。それは大きな仕事でした。
歴史的に、これはSMPのサポートの増加(マルチCPUサポート)によって非常に緊急に行われました。初めて、実際にはマルチCPUメインボードがありました。後に複数のCPU(「コア」)が単一のチップに統合されましたが、今日では、実際にマルチCPUのマザーボードはすでにまれです(通常、高価なサーバーシステムにあります)。また、実際にシングルコアシステム(単一のコアを持つ単一のCPUのみが存在する場合)もまれです。
したがって、あなたの質問に対する答えは、「先制的ではない理由」ではありません。なぜなら、それは常に先制的だったからです。本当の問題は、プリエンプティブカーネルの実行が本当に必要な理由です。その答えは、メニーCPU、メニーコアシステムの比率の増加です。
これは技術的な答えではなく、OPが提起した特定の質問に対する歴史的な答えです。「古いLinuxカーネルのプリエンプティビティがない理由は何ですか?」
(私は、彼の答えとコメントで@peterhによって説明されているように、「非プリエンプティビティ」によってOPは1つのユーザープロセスのみがカーネル内(API内)にあるという事実のいずれかまたは両方を指していると仮定します時間および/またはビッグカーネルロック。)
Linus Torvaldsはオペレーティングシステムがどのように機能するかを学ぶことに興味があり、彼が学んだ方法はそれを書くことでした。彼のモデル、ベース、および初期開発環境はMinixでした。教育目的のための既存のOS(つまり、運用OSではありません)は無料ではありませんでした(当時のオープンソースのように-ビールのように無料ではありませんでしたが、どちらか)。
だから彼はプリエンプションなしでカーネルを書いた(他の回答で言及されているビッグカーネルロック)それはあなたが新しいOSを教育目的のために迅速に立ち上げて実行したい場合にそれを行う方法だからです:それははるかにはるかに簡単です。ユーザープログラムとデバイスの同時マルチプログラミングをサポートするカーネルは十分に困難です- カーネル自体を並行にすることは非常に困難です。
彼がLinuxの人気/有用/重要性を知っていたら、おそらく同じ方法でそれを行っていたでしょう。(IMOのみ、私は彼が実際に何を考えているのか分かりません。)走る前にあなたは歩かなければならないからです。
そして、a)現在のLinux(または当時のLinux)を作成するために他に多くの作業を行う必要があり、b)変更することは大きな困難な仕事であるため、それは長い間そのようにとどまりました(他の回答で説明されているように)。