Was ist eigentlich los, wenn du einen Thread schläfst ?
Ich sehe, dass das Schlafen eines Threads "den aktuellen Thread für einen bestimmten Zeitraum pausiert" . Aber wie funktioniert das?
Laut Wie funktioniert Thread.sleep () intern und wie funktioniert Thread.sleep wirklich? ::
- Die Schlafdauer unterliegt einer gewissen systemspezifischen Granularität
- Der Schlaf blockiert
- Der Thread verlässt die CPU und stoppt die Ausführung
- Der Thread verbraucht im Ruhezustand keine CPU-Zeit
Ich kann die interne und grundlegende Mechanik dessen, was dies alles bedeutet, einfach nicht ganz verstehen.
Ich verstehe, dass es einen sogenannten Scheduler gibt, der für das Wechseln zwischen Threads verantwortlich ist.
Quellen scheinen darauf hinzuweisen, dass dies je nach Betriebssystem (oder Hardware?) Variiert und die meisten Threads 1 ms - 60 ms oder so erhalten, um einige Aktionen auszuführen, bevor die CPU zu einem anderen Thread wechselt.
Aber wenn ein Thread in den Ruhezustand versetzt wird (z. B. viele Sekunden), wie wird er fortgesetzt? Ich vermute, dass ein Timer irgendwie involviert ist. Ist es die Uhr des Motherboards? Bezieht es sich auf die CPU-Taktrate?
Und selbst wenn ein Timer beteiligt ist, woher weiß die CPU, wann es Zeit ist, wieder auf den Thread zu achten? Müsste es nicht ständig im Thread nachsehen, ob es fertig ist? Ist das nicht effektiv Polling und deshalb Art ist raubend CPU - Zeit?
Ist das Schlafen ein Thread sprachspezifisch oder ist das Betriebssystem dafür verantwortlich oder ist es eine CPU-spezifische Sache?
Würde mir das bitte jemand mit grundlegenden Erklärungen zu Dingen wie dem Scheduler und dem, was die CPU während all dem tut, erklären?
quelle
Antworten:
Das Ausführen eines Programms umfasst viel mehr als nur den Code in diesem Programm.
Jedes Programm, das in einem Multiprozess-Betriebssystem ausgeführt wird, unterliegt der Kontrolle des Schedulers des Betriebssystems. Der Scheduler verwaltet eine explizite Tabelle, in der angegeben ist, welcher Prozess ausgeführt wird, welche darauf warten, ausgeführt zu werden, wenn CPU-Zyklen verfügbar sind, und welche nicht gerade sind versuchen zu rennen (schlafen). Der Scheduler weist Prozessen in der Regel Zeitscheiben mit gerader Größe zu, abhängig von ihrer Priorität und ihrem Ausführungsverlauf. Letztendlich wird diese Schleife durch Hardware-Interrupts gesteuert, die normalerweise von einem Oszillator auf der Hauptplatine erzeugt werden.
Sleeping ist immer eine Funktion, die eine Programmiersprache nur unterstützen kann, weil die Laufzeitumgebung, in der sie ausgeführt wird, dies unterstützt. Ein normales Programm kann nicht aussetzen selbst , kann er nur dem Scheduler sagen , wie es würde gerne behandelt werden - und der Planer ist keineswegs verpflichtet , oder sogar immer in der Lage diesen Wunsch zu erfüllen. Stellen Sie sich vor, ein Laptop wird geschlossen und befindet sich im Winterschlaf. Der Oszillator der Hauptplatine pulsiert weiter, aber da der Scheduler nicht läuft, kann auch kein Prozess ausgeführt werden, egal wie hoch seine Priorität ist.
quelle
Wie Doc Brown in einem Kommentar erwähnt hat, sind Interrupts der Schlüssel und nicht nur zum Schlafen.
Ein Interrupt ist ein Hardware-Signal, dass der Prozessor anhalten und einen Code ausführen soll. Externe Geräte lösen Interrupts aus, wenn sie die Aufmerksamkeit des Prozessors benötigen: Zum Beispiel, wenn eine Festplatte das Lesen von Daten beendet hat oder eine Taste gedrückt wurde oder ein Countdown-Timer auf dem Motherboard Null erreicht hat.
Interrupt-Handling-Code ist im Allgemeinen sehr klein und sehr schnell. Wenn die Festplatte beispielsweise anzeigt, dass ein Block in den Speicher kopiert wurde, zeichnet das Betriebssystem diese Tatsache möglicherweise einfach in einer Liste von "fertigen Blöcken" irgendwo auf und kehrt dann zu dem zurück, was es gerade getan hat. Sie möchten nicht, dass die CPU ihre gesamte Zeit mit Interrupt-Handling-Code verbringt und keinen Benutzercode ausführt.
Ein Teil des Interrupt-gesteuerten Codes, der nicht unbedingt klein ist, ist der Scheduler. Es wird durch ein Signal von einem Countdown-Timer ausgelöst und überprüft den Status des Systems, wann immer es ausgeführt wird. Dies umfasst in der Regel die Identifizierung von Prozessen, die zur Ausführung bereit sind (z. B. weil der Block, auf den sie gewartet haben, im Speicher angekommen ist) sowie von Prozessen, die ihre Zeitscheibe erschöpft haben.
Wenn Sie also einen Thread-Schlaf ausführen, teilen Sie dem Betriebssystem mit, dass (1) Sie Ihre Zeitscheibe aufgeben und (2) Sie erst nach Ablauf einer bestimmten Zeit wieder geweckt werden sollten.
Immer wenn der Scheduler ausgeführt wird, wird Ihr Thread angezeigt und nur dann als "betriebsbereit" markiert, wenn diese Zeit abgelaufen ist. Dies ist eine Art Abfrage, aber keine Abrufschleife, da sie durch einen Interrupt ausgelöst wird. Es ist auch nicht so teuer: Normalerweise laufen nur ungefähr tausend Threads gleichzeitig.
Dies sollte Ihnen auch eine Vorstellung davon geben, warum die Ruhezeiten nicht genau sind: Wenn Ihr Thread zur Ausführung bereit ist, werden möglicherweise andere Threads noch ausgeführt und haben ihre Zeitscheibe nicht ausgeschöpft. Oder es gibt Threads mit höherer Priorität, die zur Ausführung bereit sind.
quelle