[Notizen lesen] Linux-Kernel-Design und Planung des Implementierungsprozesses

Prozessplanung: Der Kernel entscheidet auf diese subtile und interessante Weise, welcher Prozess wann und in welcher Reihenfolge ausgeführt wird.

Prozesse erscheinen dem Betriebssystem als laufende Form des Programms.

Ein Prozessplaner (kurz Scheduler) kann als Kernel-Subsystem angesehen werden , das begrenzte Prozessorzeitressourcen zwischen ausführbaren Prozessen zuweist .

Das Prinzip der maximalen Nutzung der Prozessorzeit durch den Scheduler lautet: Solange Prozesse ausgeführt werden können, werden immer Prozesse ausgeführt.

Die Auswahl eines aus einer Reihe von Prozessen in einem laufenden Zustand zur Ausführung ist die grundlegende Arbeit, die der Scheduler benötigt.

1. Multitasking-Preemption, Zeitscheiben und Zugeständnisse

Ein Multitasking-Betriebssystem ist ein Betriebssystem, das mehrere Prozesse gleichzeitig und interaktiv gleichzeitig ausführen kann.
Ob auf einem Einzelprozessor- oder einem Multiprozessor-Computer, ein Multitasking-Betriebssystem kann mehrere Prozesse in einem blockierten oder Ruhezustand halten, dh sie werden nicht tatsächlich ausgeführt, da sie wissen, dass die Arbeit tatsächlich bereit ist.

Multitasking-Systeme können unterteilt werden in: nicht präemptives Multitasking (kooperatives Multitasking) und präemptives Multitasking (präemptives Multitasking).

F: Was ist Vorkaufsrecht?
A: Der Scheduler entscheidet, wann die Ausführung eines Prozesses gestoppt werden soll, damit andere Prozesse die Möglichkeit zur Ausführung erhalten. Diese erzwungene Unterbrechungsaktion wird als Preemption bezeichnet.

F: Was ist eine Zeitscheibe (Zeitscheibe)?
A: Die Zeit, die der Prozess ausgeführt werden kann, bevor er vorab freigegeben wird, wird im Voraus festgelegt. Diese Zeit ist die Zeitscheibe des Prozesses.

F: Was ergibt sich?
A: Der Prozess, der sein eigenes Betriebssystem aktiv unterbricht, wird als Nachgeben bezeichnet.

Die Vor- und Nachteile von präemptiven und nicht präemptiven Typen liegen auf der Hand: In einem nicht präemptiven Multitasking-Modus können andere Prozesse ausgeführt werden, sofern der Prozess nicht aktiv nachgibt. Der Suspendierungsprozess kann das System zum Absturz bringen.

2. Linux Process Scheduling-O (1) Scheduler

3. Strategie - Entscheiden Sie, wann und welchen Prozess der Scheduler ausführen soll

3.1 E / A-verbrauchende und prozessorintensive Prozesse

Prozesse können in E / A-Verbrauch und Prozessorverbrauch unterteilt werden.
E / A-Verbrauch bedeutet, dass der größte Teil des Prozesses zum Senden von E / A-Anforderungen oder zum Warten auf E / A-Anforderungen verwendet wird.
Prozessorverbrauch bedeutet, dass der Prozess die meiste Zeit damit verbringt, Code auszuführen. Sofern sie nicht vorbelegt sind, laufen sie normalerweise ohne Unterbrechung.

ps: Der Prozess kann beide anzeigen, dh sowohl den E / A-Verbrauchstyp als auch den Prozessorverbrauchstyp.

Planungsstrategien zielen normalerweise darauf ab, zwei widersprüchliche Ziele auszugleichen: Der Prozess ist entsprechend schnell (kurze Reaktionszeit) und maximale Systemauslastung (hoher Durchsatz) .

3.2 Prozesspriorität

Der grundlegendste Typ eines Planungsalgorithmus ist die prioritätsbasierte Planung.
Der Scheduler wählt immer den Prozess mit der höchsten Priorität aus und die Zeitscheibe ist nicht erschöpft.

Linux verwendet zwei verschiedene Prioritätsbereiche. Guter Wert und Echtzeitpriorität

Typ Erklärung
schönes Preis-Leistungs-Verhältnis 1: Der Bereich reicht von -20 bis +19, der Standardwert ist 0;
2: Der größere nette Wert bedeutet niedrigere Priorität;
3: Der zugehörige Befehl ps -el, die NI-Spalte ist der schöne Wert für den Prozess
Echtzeitpriorität 1: Der Wert kann konfiguriert werden;
2: Der Standardbereich variiert von 0 bis 99 (einschließlich);
3: Ein höherer Echtzeitprioritätswert bedeutet eine höhere Prozesspriorität;
4: Jede Echtzeitprozesspriorität ist höher als ein gewöhnlicher Prozess (Echtzeitpriorität und nette Priorität sind in zwei nicht zusammenhängende Kategorien unterteilt.)
5: Verwandte Befehle: ps-eo-Status, uid, pid, ppid, rtprio, Zeit, comm () Details wie unten gezeigt
ps -eo state,uid,pid,ppid,rtprio,time,comm

Fügen Sie hier eine Bildbeschreibung ein

3.3 Zeitscheibe

Eine Zeitscheibe ist ein numerischer Wert, der angibt, wie lange ein Prozess noch ausgeführt werden kann, bevor er vorab freigegeben wird.

Die Erfahrung zeigt, dass jeder Langzeitfilm zu einer schlechten Systeminteraktionsleistung führt.

Der CFS-Scheduler (Completely Fair Scheduling) von Linux ordnet Prozessen keine Zeitscheiben direkt zu, sondern teilt den Prozessorauslastungsgrad den Prozessen auf.
Daher hängt die durch den Prozess gewonnene Prozessorzeit tatsächlich eng mit der Systemlast zusammen. Und dieses Verhältnis wird auch durch den netten Wert des Prozesses beeinflusst. Der nette Wert als Gewicht passt das vom Prozess verwendete Prozessorzeit-Nutzungsverhältnis an.

Linux ist präemptiv. Wenn ein Prozess in einen ausführbaren Zustand wechselt, kann er im Linux-CFS-Scheduler ausgeführt werden. Der Zeitpunkt der Preemption hängt davon ab, wie viel Prozessornutzung das neue ausführbare Programm verbraucht. Wenn die verbrauchte Nutzung geringer ist als der aktuelle Prozess, wird der neue Prozess sofort in Betrieb genommen, wodurch der aktuelle Thread ausgeschlossen wird. Andernfalls wird er verzögert.

3.4 Planen von Strategieaktivitäten - Es wird empfohlen, diesen Abschnitt des Originalbuchs zu lesen, in dem die "Strategie" klar beschrieben wird.

4. Linux-Planungsalgorithmus

ps: springe vorübergehend zu Kapitel 11

4.1 Scheduler-Klassen (Scheduler-Klassen) - modularer Aufbau

Der Linux-Scheduler wird als Modul bereitgestellt. Ziel ist es, verschiedenen Prozesstypen die gezielte Auswahl von Scheduling-Algorithmen zu ermöglichen.

Die Scheduler-Klasse ermöglicht mehrere verschiedene Scheduling-Algorithmen, die dynamisch hinzugefügt werden können, um Prozesse zu koexistieren und zu planen, die zu ihrer eigenen Kategorie gehören.

Jeder Scheduler hat eine Priorität, und der grundlegende Scheduler-Code ist in der Datei kernel / sched.c definiert.

Vollständig faires Scheduling (CFS) ist eine Scheduling-Klasse für normale Prozesse mit dem Namen SCHED_NORMAL unter Linux (unter POSIX mit dem Namen SCHED_OTHER). Die Implementierung des CFS-Algorithmus ist in der Datei kernel / sched_fair.c definiert.

4.2 Prozessplanung in Unix-Systemen

4.3 Fair Scheduling-CFS

Der Ausgangspunkt von CFS basiert auf einem einfachen Konzept: Die Prozessplanung sollte so wirken, als ob das System über einen idealen perfekten Multitasking-Prozessor verfügt.

In diesem System kann jeder Prozess 1 / n Prozessorzeit erhalten - n bezieht sich auf die Anzahl der ausgeführten Prozesse.

Das obige ideale Modell ist nicht realistisch, da es unmöglich ist, mehrere Prozesse gleichzeitig auf einem Prozessor auszuführen.

Die Praxis von CFS besteht darin, jedem Prozess zu erlauben, für einen bestimmten Zeitraum ausgeführt zu werden, sich zu drehen und zu drehen und den Prozess auszuwählen, der am wenigsten als nächster laufender Prozess ausgeführt wird, anstatt die Methode zum Zuweisen von Zeitscheiben für jeden Prozess zu übernehmen.

CFS berechnet anhand der Gesamtzahl aller Prozesse, die ausgeführt werden können, wie lange ein Prozess ausgeführt werden soll, anstatt sich bei der Berechnung der Zeitscheibe auf den netten Wert zu verlassen.

Der nette Wert wird als Gewicht des Prozessorlaufverhältnisses verwendet, das durch den Prozess in CFS erhalten wird: Je höher der nette Wert (niedrigere Priorität), desto geringer ist das Prozessornutzungsgewicht des Prozesses, das relativ zum Standardprozess für den schönen Wert ist . Umgekehrt erhalten Prozesse mit niedrigeren Nizza-Werten (höhere Priorität) höhere Prozessorgewichte.

Jeder Prozess wird in allen ausführbaren Prozessen gemäß der "Zeitscheibe" seines Gewichts ausgeführt. Um genaue Zeitscheiben zu berechnen, legt CFS ein Ziel für den ungefähren Wert eines unendlich kleinen Planungszeitraums in perfektem Multitasking fest. " Zielverzögerung ".

CFS führt die unterste Zeile der Zeitscheibe ein, die durch jeden Prozess erhalten wird, was als minimale Granularität bezeichnet wird .

Nur der relative Wert beeinflusst das Verteilungsverhältnis der Prozessorzeit.

5. Implementierung von Linux scheduling-kernel / sched_fair.c

5.1 Zeitrechnung

Alle Scheduler müssen die Laufzeit des Prozesses verfolgen.
Wenn die Zeitscheibe eines Prozesses auf 0 reduziert wird, wird sie von einem anderen ausführbaren Prozess ausgeschlossen, der nicht auf 0 reduziert wurde.

CFS hat nicht mehr das Konzept von Zeitscheiben, sondern muss auch die Zeitabrechnung für jeden ausgeführten Prozess beibehalten, um sicherzustellen, dass jeder Prozess nur innerhalb der ihm zugewiesenen Prozessorzeit fair ausgeführt wird.
CFS verwendet die Scheduler-Entitätsstruktur, die in der struct sched_entity in der Datei <linux / sched.h> definiert ist, um den Prozess der Ausführung der Buchhaltung zu verfolgen.

ps: Die Scheduler-Entitätsstruktur ist als Mitgliedsvariable mit dem Namen se in die Prozessdeskriptorstruktur task_struct eingebettet.

Die Variable vruntime (definiert in struct sched_entity) speichert die virtuelle Laufzeit des Prozesses. Die Berechnung der Laufzeit (die für den Operator aufgewendete Zeit) wird durch die Gesamtzahl aller ausführbaren Prozesse normalisiert.

CFS verwendet die Variable vruntime, um aufzuzeichnen, wie lange ein Programm ausgeführt wurde und wie lange es ausgeführt werden sollte.

Die in der Datei kernel / sched_fair.c definierte Funktion update_curr () implementiert diese Abrechnungsfunktion.

5.2 Prozessauswahl - CFS-Planungsalgorithmus: Wählen Sie den Prozess mit dem kleinsten vruntime-Wert aus

CFS verwendet einen rot-schwarzen Baum (rbtree, selbstausgleichender binärer Suchbaum), um eine Warteschlange ausführbarer Prozesse zu organisieren und den Prozess mit dem kleinsten vruntime-Wert schnell zu finden.

  1. Wähle die nächste Aufgabe aus.
  2. Fügen Sie dem Baum Prozesse hinzu.
  3. Löschen Sie den Prozess aus dem Baum.

5.3 Scheduler-Eingang

Der Haupteinstiegspunkt für die Prozessplanung ist der Funktionsplan (), der in kernel / sched.c definiert ist.
Dies ist der Einstiegspunkt, über den andere Teile des Kernels den Prozessplaner aufrufen: Wählen Sie aus, welcher Prozess ausgeführt werden kann und wann er in Betrieb genommen werden soll.

Schedule () muss normalerweise einer bestimmten Scheduling-Klasse zugeordnet werden, dh es wird eine Scheduling-Klasse mit der höchsten Priorität gefunden. Letztere muss über eine eigene ausführbare Warteschlange verfügen und diese dann fragen, wer als nächstes ausgeführt wird Prozess.

Die Zeitplanimplementierung ist recht einfach und ruft pick_next_task () auf (auch in der Datei kernel / sched.c definiert).

pick_next_task () überprüft jede Planungsklasse in der Reihenfolge ihrer Priorität von hoch nach niedrig und wählt den Prozess mit der höchsten Priorität aus der Planungsklasse mit der höchsten Priorität aus .

Die Implementierung von pick_next_task () in CFS ruft pick_next_entity () auf, und diese Funktion ruft die in 5.2 oben beschriebene Funktion __pick_next_entity () auf.

ps: CFS ist eine Planungsklasse für normale Prozesse. Weitere Informationen finden Sie in diesem Artikel. Linux System Process Scheduling - Detaillierte Analyse der Planungsarchitektur

5.4 Schlafen und aufwachen

Der schlafende (blockierte) Prozess befindet sich in einem speziellen nicht ausführbaren Zustand .

Es gibt viele Gründe für den Prozess zu schlafen, aber es geht definitiv darum, auf einige Ereignisse zu warten.

Der Sleep-Wakeup-Vorgang des Kernels ist derselbe :
sleep : Der Prozess markiert sich selbst als ruhend, verlässt den ausführbaren rot-schwarzen Baum, stellt ihn in die Warteschlange und ruft Schedule () auf, um einen anderen Prozess auszuwählen und auszuführen.
Aufwachen : Der Prozess des Aufwachens ist genau das Gegenteil von Schlafen. Der Prozess wird in den ausführbaren Zustand versetzt und dann von der Warteschlange in den ausführbaren roten und schwarzen Baum verschoben.

Warteschlange (Ruhezustand) : Der Ruhezustand
wird von der Warteschlange verarbeitet.
Die Warteschlange ist eine einfache verknüpfte Liste, die aus Prozessen besteht, die auf das Auftreten bestimmter Ereignisse warten .
Der Kernel verwendet wake_queue_head_t, um die Warteschlange darzustellen.
Die Warteschlange kann statisch über DECLARE_WAITQUEUE () oder dynamisch über init_waitqueue_head () erstellt werden.

Der Prozess fügt sich einer Warteschlange hinzu, indem die folgenden Schritte ausgeführt werden:

  1. Rufen Sie das Makro DEFINE_WAIT () auf, um ein Warteschlangenelement zu erstellen.
  2. Rufen Sie add_wait_queue () auf, um sich der Warteschlange hinzuzufügen. Die Warteschlange aktiviert den Prozess, wenn die Wartebedingungen erfüllt sind. Natürlich müssen wir relevanten Code an anderen Stellen schreiben und die Operation wake_up () in der Warteschlange ausführen, wenn das Ereignis eintritt.
  3. Rufen Sie die Methode prepare_to_wait () auf, um den Status des Prozesses in TASK_INTERRUPTIBLE oder TASK_UNINTERRUPTIBLE zu ändern. Und diese Funktion fügt den Prozess bei Bedarf wieder in die Warteschlange ein, was beim nächsten Durchlaufen der Schleife erforderlich ist.
  4. Wenn der Status auf TASK_INTERRUPTIBLE gesetzt ist, weckt das Signal den Prozess. Dies wird als falsches Aufwecken bezeichnet (Aufwecken ist nicht auf ein Ereignis zurückzuführen). Überprüfen und verarbeiten Sie das Signal.
  5. Wenn der Prozess aufgeweckt wird, wird erneut geprüft, ob die Bedingung erfüllt ist. Wenn dies der Fall ist, verlässt es die Schleife. Wenn nicht, ruft es Schedule () erneut auf und wiederholt diesen Schritt die ganze Zeit.
  6. Wenn die Bedingungen erfüllt sind, ändert der Prozess seine Schlange in TASK_RUNNING und ruft die Methode finish_wait () auf, um sich aus der Warteschlange zu entfernen.

z.B:

/* 'q' 是希望休眠的等待队列 */
DEFINE_WAIT(wait);

add_wait_queue(q,&wait);
while(!condition){ /* 'condition' 是在等待的事件 */
	prepare_to_wait(&q,&wait,TASK_INTERRUPTIBLE);
	if(signal_pending(current))
	{
		/* 处理信号 如:*/
		/* do_something; */
	}
	schedule();
};
finish_wait(&q,&wait);

ps: Wenn Sie immer noch Sperren haben, wenn Sie schlafen möchten, denken Sie daran, die Sperren aufzuheben, bevor Sie Schedule () aufrufen, und sie anschließend erneut abzurufen oder auf andere Ereignisse zu reagieren.

Die Funktion inotify_read () befindet sich in der Datei fs / notify / inotify / inotify_user.c und kopiert die aus dem Deskriptor der Benachrichtigungsdatei gelesenen Informationen. Ihre Implementierung ist eine typische Verwendung der Warteschlange (dieselbe serielle Kommunikation des tty-Geräts n_tty.c) Die Funktion n_tty_write () ist auch eine typische Verwendung der Warteschlange.

Wach auf :
Weck- Betrieb wake_up () -Funktion durch, es wacht alle Prozesse auf der spezifizierten Warteschlange.
Die Funktion wake_up ruft try_to_wake_up () auf, das den Prozess kopiert, um den Prozess in den Status TASK_RUNNING zu versetzen, und enqueue_task () aufruft, um den Prozess in den rot-schwarzen Baum zu setzen. Sie müssen das Flag need_resched setzen.

ps: Welcher Code normalerweise dazu führt, dass die Wartebedingung abgeschlossen wird, kopiert und ruft dann die Funktion wake_up () auf.
ps: Eine Sache, die man im Winterschlaf beachten sollte, ist falsches Aufwachen. Das heißt, manchmal wird der Prozess nicht aktiviert, weil er darauf wartet, dass die Bedingung erfüllt wird. Es ist erforderlich, einen zirkulären Prozess zu verwenden, um sicherzustellen, dass die Bedingung, auf die er wartet, tatsächlich erfüllt ist.
Fügen Sie hier eine Bildbeschreibung ein

6. Preemption und Kontextwechsel

Das Umschalten des Kontexts, dh das Umschalten von einem ausführbaren Prozess zu einem anderen, wird von der in kernel / sched.c definierten Funktion context_switch () durchgeführt.
Immer wenn ein neuer Prozess ausgewählt und zur Ausführung bereit ist, ruft Schedule () diese Funktion auf.
Die Funktion context_switch () führt die folgenden zwei grundlegenden Aufgaben aus:

  1. Rufen Sie switch_mm () auf, das in <asm / mmu_context.h> deklariert ist. Diese Funktion ist für das Umschalten des virtuellen Speichers von der vorherigen Prozesszuordnung auf den neuen Prozess verantwortlich.
  2. Rufen Sie switch_to () auf, das in <asm / system.h> deklariert ist. Diese Funktion ist für das Umschalten vom Prozessorstatus des vorherigen Prozesses in den Prozessorstatus des neuen Prozesses verantwortlich. Jeder Prozess muss verwaltet und gespeichert werden, einschließlich Speichern, Beantworten von Stapelinformationen und Registerinformationen sowie anderer Statusinformationen in Bezug auf die Architektur.

Der Kernel muss wissen, wann er Schedule () aufrufen muss. Ein Need_resched-Flag gibt an, ob die Planung erneut ausgeführt werden muss.

Die Funktionen für den Zugriff auf und den Betrieb von need_resched lauten wie folgt:

Funktion Zweck
set_tsk_need_resched () Setzen Sie das Flag need_resched im angegebenen Prozess
clear_tsk_need_resched () Löschen Sie das Flag need_resched im angegebenen Prozess
need_resched () Überprüfen Sie den Wert des Flags "need_resched" und geben Sie "true" zurück, falls gesetzt, andernfalls "false"

F: Wann wird das Flag need_resched gesetzt?
A: Wenn ein Prozess vorbelegt werden soll, setzt scheduler_tick () dieses Flag. Wenn ein Prozess mit hoher Priorität in den ausführbaren Status wechselt, setzt try_to_wake_up dieses Flag. Der Kernel überprüft das Flag, um zu bestätigen, dass es gesetzt ist Rufen Sie Zeitplan () auf, um zu einem neuen Prozess zu wechseln. Wenn der Kernel zum Benutzerbereich zurückkehrt und von einem Interrupt zurückkehrt, überprüft er auch das Flag need_resched. Wenn es gesetzt ist, ruft der Kernel den Scheduler auf, bevor er die Ausführung fortsetzt.

Jeder Prozess enthält ein need_resched-Flag, da der Zugriff auf den Wert im Prozessdeskriptor schneller ist als der Zugriff auf eine globale Variable (da das aktuelle Makro schnell ist und sich der Deskriptor normalerweise im Cache befindet). Need_resched nach Version 2.6 wurde in die Struktur thread_info verschoben und durch ein Bit in einer speziellen Flag-Variablen dargestellt.

6.1 Benutzerpräferenz

Wenn der Kernel in den Benutzerbereich zurückkehren soll und das Flag "need_resched" gesetzt ist, wird "sched ()" aufgerufen und die Benutzerpräferenz erfolgt.

Die Benutzerfreigabe erfolgt, wenn:

  1. Wenn Sie von einem Systemaufruf zum Benutzerbereich zurückkehren;
  2. Wenn Sie von einem Interrupt-Handler zum Benutzerbereich zurückkehren.

6.2 Kernel-Preemption - Solange die Sperre nicht gehalten wird, kann der Kernel Preemption durchführen

Linux unterstützt die Kernel-Preemption vollständig. Das heißt, der Scheduler kann einen neuen Zeitplan erstellen, während eine Aufgabe auf Kernelebene ausgeführt wird.

Solange die Planung sicher ist, kann der Kernel die Ausführung der Aufgabe jederzeit verhindern.

F: Wann ist eine Umplanung sicher?
A: Solange die Sperre nicht gehalten wird, kann der Kernel vorbeugen. Das Schloss ist ein Zeichen für einen nicht vorgezogenen Bereich.

Die Kernel-Vorauszahlung erfolgt, wenn:

  1. Der Interrupt-Handler wird ausgeführt und bevor er in den Kernelbereich zurückkehrt.
  2. Wenn der Kernel-Code wieder vorbelegt werden kann;
  3. Wenn die Aufgabe im Kernel explizit Schedule () aufruft;
  4. Wenn die Aufgabe im Kernel blockiert ist (dies führt auch dazu, dass Schedule () aufgerufen wird).

ps: Die erste Änderung zur Unterstützung der Kernel-Preemption besteht darin, für jeden Prozess einen preempt_count-Zähler für thread_info einzuführen. Der Anfangswert des Zählers ist 0, und der Wert erhöht sich bei jeder Verwendung der Sperre um 1 und verringert sich um 1, wenn die Sperre aufgehoben wird. Wenn der Wert 0 ist, kann der Kernel eine Vorauszahlung durchführen.

7. Echtzeit-Planungsstrategie-SCHED_FIFO und SCHED_RR

Linux bietet zwei Echtzeit-Planungsstrategien: SCHED_FIFO und SCHED_RR.
Die übliche Nicht-Echtzeit-Planungsstrategie lautet SCHED_NORMAL.

Die Echtzeitstrategie wird nicht vom Late Fair Scheduler verwaltet, sondern von einem speziellen Echtzeit Scheduler . Die Implementierung ist in der Datei kernel / sched_rt.c definiert.

Echtzeit-Planungsstrategie Detaillierte Beschreibung Gleiches
SCHED_FIFO SCHED_FIFO implementiert einen einfachen First-In-First-Out- Planungsalgorithmus: Es werden keine Zeitscheiben verwendet. Prozesse auf SCHED_FIFO-Ebene, die ausgeführt werden, werden vor Prozessen auf SCHED_NORMAL-Ebene geplant. Sobald sich ein Prozess auf SCHED_FIFO-Ebene in einem ausführbaren Zustand befindet, wird er weiter ausgeführt, bis er blockiert wird oder den Prozessor explizit freigibt. Er basiert nicht auf Zeitscheiben und kann weiterhin nur SCHED_FIFO- oder SCHED_RR-Tasks mit höherer Priorität ausführen Um die Aufgabe SCHED_FIFO zu verhindern. Wenn es zwei oder mehr Prozesse auf SCHED_FIFO-Ebene auf Prioritätsebene gibt, werden diese nacheinander ausgeführt, aber sie wurden nur freigegeben, wenn sie bereit sind, den Prozessor aufzugeben. Solange ein Prozess auf SCHED_FIFO-Ebene ausgeführt wird, können andere Prozesse auf niedrigerer Ebene nur warten, bis er nicht mehr funktionsfähig ist, bevor sie ausgeführt werden können Was erreicht wird, ist statische Priorität . Der Kernel berechnet keine dynamischen Prioritäten für Echtzeitprozesse. Dies stellt sicher, dass Echtzeitprozesse einer bestimmten Prioritätsstufe immer Prozesse mit einer niedrigeren Priorität als dieser verhindern können
SCHED_RR SCHED_RR ist ungefähr dasselbe wie SCHED_RR, außer dass der Prozess auf SCHED_RR-Ebene die Ausführung nicht fortsetzen kann, nachdem die ihm im Voraus zugewiesene Zeit erschöpft wurde. Mit anderen Worten, SCHED_RR ist SCHED_FIFO mit Zeitscheiben - dies ist ein Echtzeit-Rotationsplanungsalgorithmus . Wenn die SCHED_RR-Task keine Zeitscheiben mehr hat, werden nacheinander andere Echtzeitprozesse mit derselben Priorität geplant. Zeitscheiben werden nur verwendet, um Prozesse mit derselben Priorität neu zu planen. Für den SCHED_FIFO-Prozess steht die niedrige Priorität immer unmittelbar vor der niedrigen Priorität, aber der Prozess mit niedriger Priorität darf die SCHED_RR-Task nicht vorwegnehmen, selbst wenn ihre Zeitscheibe erschöpft ist. Was erreicht wird, ist statische Priorität. Der Kernel berechnet keine dynamischen Prioritäten für Echtzeitprozesse. Dies stellt sicher, dass Echtzeitprozesse einer bestimmten Prioritätsstufe immer Prozesse mit einer niedrigeren Priorität als dieser verhindern können

Der Echtzeit-Planungsalgorithmus von Linux bietet eine weiche Echtzeit- Arbeitsmethode. Die Bedeutung von Soft Real Time ist: Der Kernel plant den Prozess und versucht, den Prozess vor seiner begrenzten Zeit auszuführen. Der Kernel garantiert jedoch nicht, dass er die Anforderungen dieser Prozesse immer erfüllen kann.

Die Echtzeitpriorität reicht von 0 bis MAX_RT_PRIO minus 1 (0-99). Standardmäßig ist MAX_RT_PRIO 100.
Der nette Wert des Prozesses der Ebene SCHED_NORMAL teilt sich diesen Wertebereich, sein Wertebereich reicht von MAX_RT_PRIO bis (MAX_RT_PRIO + 40), dh standardmäßig entspricht der nette Wert von -20 bis +19 direkt 100 bis 139 Echtzeit-Prioritätsbereich.

8. Systemaufrufe im Zusammenhang mit der Planung

Linux bietet eine Reihe von Systemaufrufen zum Verwalten von Parametern, die sich auf den Scheduler beziehen.
Die mit der Planung verbundenen Systemaufrufe sind in der folgenden Tabelle aufgeführt

Systemaufruf Beschreibung
nett() Stellen Sie den netten Wert des Prozesses ein
sched_setscheduler () Festlegen der Prozessplanungsstrategie
sched_getscheduler () Holen Sie sich die Planungsstrategie des Prozesses
sched_setparam () Legen Sie die Echtzeitpriorität des Prozesses fest
sched_getparam () Holen Sie sich die Echtzeitpriorität eines Prozesses
sched_get_priority_max () Erhalten Sie den Maximalwert der Echtzeitpriorität
sched_get_priority_min () Holen Sie sich den Mindestwert der Echtzeitpriorität
sched_rr_get_interval () Ruft den Zeitscheibenwert des Prozesses ab
sched_setaffinity () Stellen Sie die Affinität des Prozessors des Prozesses ein
sched_getaffinity () Holen Sie sich die Affinität des Prozessors des Prozesses
sched_yield () Geben Sie den Prozessor vorübergehend auf
Veröffentlicht 91 Originalarbeiten · erntete Lob 17 · Ansichten 50000 +

Ich denke du magst

Origin blog.csdn.net/qq_23327993/article/details/105072421
Empfohlen
Rangfolge