2016-09-23 2 views
4

Wie erfolgt die Kontextumschaltung im Linux-Kernel, wenn der Prozess vor dem Timer-Interrupt beendet wird?Linux Kontextwechsel Interna: Was passiert, wenn der Prozess vor dem Timer-Interrupt beendet wird?

Ich weiß, dass, wenn der Prozess läuft und Timer-Interrupt auftritt, schedule Funktion automatisch aufgerufen wird, wenn das Flag gesetzt ist, wählt Zeitplan-Funktion dann nächsten Prozess zu laufen. In diesem Fall läuft die Schedule-Funktion im Kontext des aktuellen Prozesses, aber was passiert, wenn der Prozess noch vor dem Timer-Interrupt beendet wird? Wer ruft in diesem Fall schedule Funktion? Und in welchem ​​Kontext läuft es?

+0

Wenn Sie gemeint haben, was passiert, wenn ein Prozess 'exits()' aufruft, dann wird in diesem Fall auch der Zeitplan aufgerufen. –

+0

viele Male Prozess kann ohne Aufruf von 'exit()' beenden. – Nullpointer

+0

In den meisten Fällen - sie kehren zum Elternteil zurück und es ist wahrscheinlich, dass sie 'exit_group()' machen, um Dinge zu beenden; was auch endete, rief 'schedule()' auf. –

Antwort

4

Es ist wichtig zu verstehen, dass der Timer-Interrupt nur einer von mehreren hundert verschiedenen Gründen ist, warum schedule aufgerufen werden könnte. Nur Programme, deren Laufzeit von Berechnungen dominiert wird, die seltener sind als man denkt, erschöpfen ihre Zeitscheibe. Es ist viel häufiger, dass Programme nur für einige Mikrosekunden - ja, Mikrosekunden - gleichzeitig ausgeführt werden, zwischen "Blockieren" in Systemaufrufen, Warten auf Benutzereingaben oder was auch immer.

Wenn ein Prozess in irgendeiner Weise beendet wird, findet letztendlich immer ein Aufruf an do_exit im (Kernel-) Kontext dieses Prozesses statt. do_exit ruft schedule als seine letzte Aktion auf, und schedulekehrt nie zu diesem Kontext zurück. Beachten Sie, dass am Ende von do_exit ein Anruf an schedule, unmittelbar gefolgt von BUG(); und einer Endlosschleife erfolgt.

Unmittelbar vor diesem, do_exit ruft exit_notify, die für das Senden SIGCHLD an dem übergeordneten Prozess und/oder Loslassen von einem Aufruf wait verantwortlich ist. So wird der Elternprozess oft bereit sein, wenn schedule aufgerufen wird, und wird ausgewählt.

do_exit freigibt auch alle dem User-Space-Zustand und ein großer Teil der Kernel-Zustand mit dem Prozess verbunden sind, gibt Speicher frei, schließt Filedeskriptoren usw. Der task_struct selbst muss überleben, bis jemand wait ruft, und ich kann nicht verstehen Genau wie der Kernel entscheidet, dass er jetzt freigegeben werden kann; Dieser Code ist zu kompliziert.

Wenn der Prozess genannt _exit, die Kette Kernel Anruf einfach ist sys_exit_group zu do_group_exit zu do_exit. Wenn ein fatales synchrones Signal (z. B. SIGSEGV) erforderlich war, ist die Anrufkette viel länger und weist eine schwierige Abzweigung auf. Die Hardware-Trap wird durch einen architekturspezifischen Code (z. B. x86 do_trap) über force_sig_info und send_signal bis complete_signal angelegt, der den Task-Status einstellt und dann dem Scheduler mitteilt, den fehlerhaften Prozess aufzuwecken. Der beleidigende Prozess wacht auf und ein Labyrinth von architekturspezifischer Signalverarbeitungslogik liefert ihn schließlich an get_signal, der do_group_exit aufruft, der do_exit ruft. Fatal asynchrone Signale (beispielsweise von kill 12345 an einer Shell-Eingabeaufforderung) an sys_kill beginnen und gehen durch kill_something_info, group_send_sig_info, do_send_sig_info zu send_signal, wonach alles wie oben verläuft. In beiden Fällen können alle Schritte bis zu complete_signal in beliebigen Prozesskontext passieren, aber alles nach dem "der beleidigende Prozess aufwacht" geschieht in diesem Kontext des Prozesses.

Die einzigen Teile dieser Beschreibung, die Linux-spezifisch sind, sind die Namen der Funktionen im Kernel-Code.Jede Implementierung von Unix wird Kernel-Funktionen haben, die mehr oder weniger was Linux do_exit und schedule tun, und die Abfolgen von Operationen beteiligt _exit, fatale synchrone Signale und fatale Async-Signale werden erkennbar ähnlich sein.

+0

Wow! das ist, was ich wirklich gesucht habe .. Danke. Auch wenn Sie bitte zur Antwort hinzufügen können, was passiert, wenn der Prozess unerwartet beendet wird, wie z. B. segfault? do_exit wird in diesem Fall nicht aufgerufen, oder? – Nullpointer

+0

Nein, tatsächlich wird 'do_exit' _will_ aufgerufen, wenn ein Prozess durch ein Signal beendet wird. Ich werde der Antwort einige Anmerkungen hinzufügen. – zwol

Verwandte Themen