タイマ割り込みは、schedule
が呼び出される数百の異なる理由の1つにすぎないことを理解することが重要です。実行時間が計算に支配されているプログラムは、思っていたよりも稀であり、タイムスライスを使い果たしてしまいます。プログラムが数マイクロ秒(マイクロ秒)で実行されるのは、システムコールの「ブロッキング」とユーザーの入力を待つこととの間で、一度に数マイクロ秒で実行する方がずっと一般的です。
プロセスが何らかの方法で終了すると、そのプロセスの(カーネル)コンテキストで最終的にdo_exit
への呼び出しが行われます。 do_exit
は最後のアクションとしてschedule
を呼び出し、schedule
は決してそのコンテキストに戻りません。ちょうどdo_exit
の最後にschedule
への呼び出しがあり、すぐにBUG();
と無限ループが続くことに注意してください。
はこの直前に、do_exit
親プロセスにSIGCHLD
を送信および/またはwait
への呼び出しから、それを解除するための責任がある、exit_notify
を呼び出します。したがって、多くの場合、schedule
が呼び出されると、親プロセスが実行準備完了になり、選択されます。誰かがwait
を呼び出すまで
do_exit
もtask_struct
自体を、ユーザ空間の状態のすべてのプロセスに関連付けられているカーネルの状態の多くの割り当てを解除するメモリを解放し、ファイルディスクリプタをクローズする、などが生き残るしなければならない、と私は理解できませんカーネルがどのように割り当て解除できるかを正確にどのように決定するか。このコードは複雑すぎます。
プロセスは_exit
を呼び出した場合は、カーネルの呼び出しチェーンは、単にsys_exit_group
do_group_exit
にdo_exit
にあります。致命的な同期信号(例:SIGSEGV
)が発生した場合、コールチェーンはかなり長くなり、その中に厄介な転用があります。ハードウェアトラップは、アーキテクチャ固有のコード(例えば、x86 do_trap
)によってforce_sig_info
とsend_signal
~complete_signal
との間でフィールド化され、タスク状態を調整し、スケジューラに問題のプロセスを起こさせる。原因となっているプロセスが目を覚ますと、アーキテクチャー固有のシグナル処理ロジックの迷路によって、最終的にget_signal
に転送され、do_group_exit
が呼び出され、do_exit
が呼び出されます。致命的な非同期信号(例えば、シェル・プロンプトでkill 12345
を入力してから)sys_kill
で開始し、すべてが上記のように進行するの後、send_signal
にkill_something_info
、group_send_sig_info
、do_send_sig_info
経ます。どちらの場合も、complete_signal
までのすべてのステップは、のプロセスコンテキスト内で発生することがありますが、そのプロセスのコンテキストでは「プロセスが起きる」の後のすべてが発生します。
Linux固有のこの説明の唯一の部分は、カーネルのコード内の関数の名前です。Unixの実装には、Linuxのdo_exit
とschedule
のような機能を果たすカーネル機能があり、偽の同期信号と致命的な非同期信号の両方に似た動作シーケンスが認識可能に似ています。
もし、プロセスが 'exits()'を呼び出すとどうなりますか?この場合は、scheduleも呼び出されます。 –
何回もプロセスは 'exit()'を呼ばずに終了できます。 – Nullpointer
これらのケースのほとんどでは、彼らは親に戻り、終了するために 'exit_group()'を実行する可能性が高いです。 'schedule()'も呼び出すことになりました。 –