Wie funktioniert Multithread, wenn die Hardware über 4 Kerne verfügt und die Software-App mehr als 4 Threads hat?

486
Angelixus

Nehmen wir an, ich habe einen Prozessor mit 4 Kernen und 4 Threads und eine Anwendung mit 20 Threads, die ich für ständige Überprüfungen benötige (sagen wir, es handelt sich um Ereignisse). Wie führt der Prozessor alle Threads gleichzeitig mit seiner begrenzten Anzahl von aus Fäden Ich weiß, dass der Prozessor von einem Thread zum anderen wechselt, und da die Änderungen so schnell sind, werden wir sie nicht bemerken, aber ist dies alles, was passiert oder der Computer etwas anderes tut? Wie speichert der Computer außerdem die Informationen für jeden Thread zu einem bestimmten Zeitpunkt, nur im RAM-Speicher?

0
Überlegen Sie, wie Single-Threading-Prozessoren damals mehrere Ausführungsthreads verwaltet haben. dsstorefile1 vor 5 Jahren 2

2 Antworten auf die Frage

2
Mokubai

20 Threads können nicht genau zur selben Zeit ausgeführt werden, außer auf einem System mit 20 oder mehr Kernen. Was das System tun kann, ist, dass es so aussieht, als würden sie fast gleichzeitig laufen.

Dafür gibt es den Betriebssystem-Scheduler.

Vor der Zeit der Multi-Core-Prozessoren musste das Betriebssystem die CPU-Zeit auf mehrere Prozesse verteilen, von denen jeder das Potenzial hatte, mehrere unterschiedliche Threads zu haben.

Das Betriebssystem muss jeden Thread verwalten, ihm eine gewisse Zeit auf der CPU zuweisen, den Status wiederherstellen, den Thread ausführen, den Status suspendieren und speichern. Nichts davon unterscheidet sich massiv zwischen Multi-Core, Multi-CPU oder Single-Core.

Was sich geändert hat, ist der Komplexitätsgrad und die Anzahl der Dinge, die gleichzeitig ausgeführt werden können. Wo wir nur einen Thread gleichzeitig ausführen konnten, können wir jetzt vier ausführen. Der gleiche Vorgang des Nachverfolgens des Thread-Status geschieht (Programmzähler usw.) und es spielt keine Rolle, wie viele Threads ein Programm hat.

Das Betriebssystem wird versuchen, alle Threads einige Zeit in der CPU einigermaßen zu planen, je nachdem, ob sie Arbeit haben (möglicherweise warten auf einen Hardware-Interrupt oder Daten von der Festplatte), welche Priorität der Prozess / Thread hat und welche Priorität er hat eine ganze Reihe anderer Dinge. Threads können das Betriebssystem darüber informieren, dass sie keine Arbeit zu erledigen haben, bis verschiedene Ereignisse eintreten und dies auf Zeit, Hardware- oder Softwareereignisse usw. zurückzuführen ist. In diesem Fall kann der Scheduler des Betriebssystems diesen Thread einfach überspringen, bis er einen Thread gefunden hat, der für die Arbeit bereit ist.

Im Moment meldet das von mir verwendete System, dass in allen Prozessen 2500 Threads vorhanden sind. Natürlich könnten alle auf einem 4-Core-Prozessor nicht gleichzeitig ausgeführt werden.

0
Jamie Hanrahan

Erstens: Eine CPU "hat" keine Threads, obwohl das Marketing Cruft versucht zu behaupten. Eine CPU kann bis zu der angegebenen Anzahl von Threads gleichzeitig laufen . Insbesondere eine CPU mit n Kernen und nicht aktiviertem Hyperthreading kann n Threads ausführen . Eine CPU mit n Kernen und aktiviertem Hyperthreading kann 2_n_-Threads ausführen. In technischen Zusammenhängen beziehen wir uns auf "die Sache, die einen Thread ausführen kann" als logischen Prozessor oder LP. Eine Maschine ohne HT-Funktion verfügt über einen LP pro Kern. HT gibt es zwei.

In einem typischen Windows-System befinden sich insgesamt Hunderte oder sogar Tausende von Threads. Dies hängt von dem Code jedes einzelnen Programms ab. Wenn Sie einen Prozess erstellen, beginnt dieser Prozess immer mit einem Thread. Einige einfache Programme, insbesondere Befehlszeilenprogramme (Zeichenmodus), verwenden möglicherweise nur einen Thread. Der Code, der in diesem ersten Thread ausgeführt wird, kann jedoch andere Threads erstellen, und diese Threads können andere Threads usw. erstellen, fast ohne praktisches Limit. Es gibt gute Gründe, nicht einfach eine große Anzahl von Threads zu erstellen, aber es gibt nichts, was es unmöglich machen würde, weitaus mehr Threads zu erstellen, als für einen Zweck gedacht wäre.

(Unter x86 gilt bei den Standardwerten für die Threadstapelgröße ein Grenzwert von etwa 2000 Threads pro Prozess - durch die Adressraumbegrenzung festgelegt.)

Auf der Registerkarte "Details" des Task-Managers können Sie die Spalte "Threads" aktivieren, in der Sie sehen, wie viele Threads derzeit in jedem Prozess vorhanden sind. Hier ist ein PowerShell-Befehl, der alle Threads in Ihrem System hochzählt:

($threads = get-ciminstance win32_thread).count 3437 

Dies ist auf einer Maschine mit vier Hyperthread-Kernen, insgesamt acht LPs.

Dies ist kein Problem, da nur sehr wenige dieser Threads tatsächlich ausgeführt werden möchten. Die meisten Threads in den meisten Prozessen verbrachten die meiste Zeit in einem Zustand, der von Windows als "wait" -Status bezeichnet wird, was bedeutet, dass sie derzeit keine CPU-Zeit beanspruchen wollen oder können. Sie warten darauf, dass die E / A (möglicherweise ein Netzwerk, möglicherweise eine Festplatte usw.) abgeschlossen ist, sie warten auf Benutzereingaben, sie warten auf einen anderen Thread, um eine Ressource freizugeben, auf die sie zugreifen müssen, usw. ( * Von Nix abgeleitete Systeme nennen dies "blockiert".)

Wenn Sie die Anzahl der wartenden Threads wünschen, versuchen Sie Folgendes:

PS C:\Users\jeh> ($threads = get-ciminstance win32_thread | where-object -Property ThreadState -EQ 5).count 3427 

Es sieht also so aus, als ob momentan nur 10 Threads versuchen, die LPs zu verwenden. Aber es ist noch besser als das. Bei 8 LPs sind 8 dieser Threads die leeren Threads des Systems. Für jede LP gibt es einen Leerlauf-Thread. Sie sind immer bereit zu laufen, aber sie laufen nur, wenn nichts anderes die LP will. Im Moment, als ich die Befehle oben ausführte, gab es nur zwei "echte" Threads, die funktionieren wollten. Die Aktivitäten der Leerlauf-Threads sind nicht in den Anzeige der CPU-Auslastung des Task-Managers enthalten.

Hinweis: Diese Zahlen sind nicht genau, da diese Powershell- und WMI-Vorgänge nicht intern mit den Funktionen des Betriebssystems synchronisiert sind. Sie sind jedoch nahe genug, um den Punkt zu veranschaulichen.

Wenn mehr Threads (außer den inaktiven Threads) "Ready" sind als deren LPs, dann wählt der Scheduler im Allgemeinen die nLPs- Threads mit der höchsten Priorität aus . Wenn mehrere Threads mit der gleichen Priorität vorhanden sind, können sie "zeitaufgelöst" sein und in einer "Round-Robin" -Methode ablaufen, wobei jeder für 20 oder 60 ms laufen soll, bevor der Scheduler die LP zu einem anderen wechselt.

Hier ist eine Antwort, die ich gegeben habe, und geht viel detaillierter auf die Funktionsweise von Thread-Prioritäten in Windows ein.