Dies ist eine allgemeine Frage, die ich mich immer gefragt habe.
Ist es für eine CPU im Allgemeinen intensiv, Threads zu erstellen, die "while not true ..." - Schleifen oder ähnliches ausführen?
Angenommen, ich mache:
// pseudo-code
new Thread(function() {
while (!useHasDoneSomething) {
// do nothing...
}
alert("you did something!");
}
Es ist also nur ein Teil des Codes, der in einem Thread ausgeführt wird, der darauf wartet, dass etwas passiert.
Aus irgendeinem Grund stelle ich mir vor, dass dies die CPU unter Druck setzen würde. Obwohl es sich nur um eine kleine Schleife handelt, wird die Schleife in dem Moment erneut ausgeführt, in dem ein Zyklus abgeschlossen ist. Würde das nicht bedeuten, dass es den Zyklus viele Male pro Millisekunde durchläuft? ... pro Nanosekunde!?
Das Betriebssystem "behandelt" das Programm und die Threads, oder? Aber das ist immer noch eine Menge Aufmerksamkeit für das Ausführen einer Schleife. Wenn die CPU nichts anderes zu tun hat, würde sie sich dann nicht einfach auf diese Schleife konzentrieren und dabei die gesamte Leerlaufzeit verbrauchen ?
Was ist, wenn ich 1000 Threads erstelle, die alle dieselbe Schleife ausführen? Wie könnte sich dies auf die Leistung / CPU-Zyklen auswirken?
Funktionieren Ereignisse auf diese Weise auch intern? Wurde ein Thread erstellt, der Schleifen erstellt, wenn Sie auf ein Ereignis in Java, .NET, Javascript usw. warten (z. B. durch Drücken einer Taste oder Ändern der Fenstergröße)?
quelle
Antworten:
Ja. Die Verwendung einer solchen Schleife wird als beschäftigtes Warten bezeichnet, und dies wird aus einem bestimmten Grund so genannt. Diese Besetztschleifen überprüfen den Zustand so oft und so schnell, wie der Prozessor ihn verwalten kann. Wenn Sie also lange genug in der Schleife bleiben, steigt die Prozessorlast zuverlässig auf 100%.
Es schafft nur mehr Arbeit für die CPU, die Notizen macht.
Nein. Busy Loops sind eine Form der Abfrage und auch eine sehr ineffiziente. Betriebssysteme verfügen über andere Mechanismen, um zu erkennen, dass ein Ereignis aufgetreten ist (z. B. ein Interrupt oder ein bestimmter Aufruf), und sie verfügen über Mechanismen, mit denen ein Thread darauf warten kann, ohne CPU-Zeit zu verbrauchen. Diese Mechanismen werden auch verwendet, um die Ereignismechanismen von Sprachen wie Java zu implementieren.
quelle
Dein Instinkt ist richtig. So beschäftigt zu warten wird beschrieben als
Stattdessen sollten Sie ein Grundelement für die Parallelitätssteuerung in Betracht ziehen, das es dem Thread ermöglicht, wirklich inaktiv zu werden, bis er nützliche Arbeit zu erledigen hat, z. B. ein Semaphor oder eine Bedingungsvariable :
quelle
if (!useHasDoneSomething)
immer wieder, so schnell es geht). Selbst wenn es Ihnen in Ihrem Programm nichts ausmacht, verschwendet es Zeit, die andere Programme zum Ausführen verwenden könnten. Aber selbst in Ihrem Programm verschwendet ein vielbeschäftigter Kellner Zeit, die einem Arbeitsthread zugewiesen werden könnte (falls nicht genügend Kerne verfügbar sind, damit alle Threads gleichzeitig ausgeführt werden können).Threads sollten auf eingehende Ereignisse warten, nicht auf Variablenänderungen.
Eingehende Ereignisse sind Semaphore, die verfügbar werden, Nachrichtenwarteschlangen werden nicht leer oder die Zeit vergeht:
Aus Thread-Sicht blockieren diese Funktionsaufrufe: Der Thread wartet, bis das Ereignis eingetreten ist, und überlässt die CPU-Last anderen Threads.
Aus Systemsicht ist der Thread als "Warten auf Ereignis" markiert und wird nicht geplant, solange das Ereignis nicht eingetreten ist.
Hardwareereignisse werden über Interrupts behandelt, die elektrische Signale an die CPU sind und die Ausführung von ISR (Interrupt Service Routines) auslösen, deren Aufgabe es ist, ein Softwareereignis auf Semaphoren, Nachrichtenwarteschlangen oder Zeit zu erzeugen.
quelle
Der
//do nothing
Teil im normalen Zustand ist WAIT auf einem Semaphor oder mit anderen Worten SLEEP. Schlaf, bis dich eine Unterbrechung geweckt hat. Und daher geht der Thread in den "Ruhezustand" oder sagen wir einfach "nicht laufender Zustand". Nur die Prozesse, die sich im laufenden Zustand befinden, verbrauchen CPU. Der Ruhezustandsprozess verbraucht keine CPU. Sie verbrauchen möglicherweise Speicher, aber dieser Speicher wird intern vom virtuellen Speichersystem ausgelagert. Selbst wenn Sie 1000 solcher Threads erstellen, stellen diese keine große Bedrohung für Ihr System dar.quelle