Wenn Sie mehrere Threads auf einem Multi-Core-Prozessor starten, werden diese garantiert von verschiedenen Cores verarbeitet?

24

Ich habe einen Pentium Core i5 Prozessor, der 4 Kerne hat. Wenn ich das in einem C # -Konsolenprogramm mache

var t1 = new Thread(Thread1);
var t2 = new Thread(Thread2);
t1.Start();
t2.Start();

Laufen T1- und T2-Threads garantiert auf separaten Kernen?

developer747
quelle
1
Angenommen, die C # -Runtime verwendet äquivalente systemeigene Systemaufrufe, um einen anderen Thread zu erzeugen (und ist daher wirklich parallel; dies ist nicht für alle Fälle wie CPythons berüchtigte globale Interpreter-Sperre der Fall ), hängt dies ausschließlich vom Prozess- / Task-Scheduler des Betriebssystems ab . Obwohl in der Regel Code ist wirklich Thread - sicher , wenn Sie davon ausgehen , dass t1und t2zu unterschiedlichen Zeiten in einer beliebigen Reihenfolge ausgeführt (zB ist es möglich t2beginnt , bevor t1 in einigen Modellen).
Durchbruch
2
Ich wusste nicht, dass es Pentium i5-Prozessoren gibt. Vielleicht meintest du Core i5? Wählerisch. Ich weiß: D
Joseph Garrone

Antworten:

18

Sie können in .Net nicht garantieren, dass zwei Threadauf zwei separaten Kernen ausgeführt werden. Tatsächlich können Sie auch nicht garantieren, dass man Threadnur auf einem Kern (!) Läuft .

Dies liegt daran, dass verwaltete Threads nicht mit Betriebssystem-Threads identisch sind. Ein einzelner verwalteter Thread verwendet möglicherweise mehrere Betriebssystem-Threads, um dies zu unterstützen. In C # arbeiten Sie immer nur direkt mit verwalteten Threads (zumindest ohne auf p / invoke zurückzugreifen, um die WinAPI-Threading-Funktionen aufzurufen, was Sie niemals tun sollten) .

Die .Net- und Windows-Thread-Scheduler sind jedoch sehr gut darin - sie würden nicht zwei Threads auf einem einzigen Kern ausführen, während ein zweiter Kern vollständig inaktiv ist. Im Allgemeinen brauchen Sie sich also keine Sorgen zu machen.

BlueRaja - Danny Pflughoeft
quelle
In der Praxis .Net Threads sind OS - Threads. Es gibt jedoch keine Garantie dafür, dass ein einzelner Thread immer auf demselben Kern ausgeführt wird.
Svick
2
@svick: In der Praxis ist dies bei x86 der Fall. Der Standard besagt jedoch ausdrücklich, dass Sie sich nicht auf dieses Verhalten verlassen können, sodass es sich in Zukunft ändern könnte. Tatsächlich trifft dies nicht auf andere Versionen der .Net CLR zu, wie z. B. XBox 360.
BlueRaja - Danny Pflughoeft
@BlueRaja - Die Frage ist spezifisch, über welche Version der CLR wir sprechen. Sie können sicherstellen, dass auf zwei separaten Kernen etwas vorhanden ist, indem Sie asynchrone Threads verwenden, da dies bedeuten würde, dass sie asynchron voneinander ablaufen würden. Der aktuelle Beispielcode ist technisch gesehen ein Synchronisationsaufruf. Natürlich entscheidet das Betriebssystem, welche Kerne verwendet werden.
Ramhound
@Ramhound "Sie können sicherstellen, dass auf zwei separaten Kernen etwas vorhanden ist, indem Sie asynchrone Threads verwenden" - das ist falsch. Das asyncSchlüsselwort (wovon Sie wahrscheinlich sprechen, da "asynchrone Threads" überflüssig sind) ist nur syntaktischer Zucker für die Verwendung eines BackgroundWorkerThreads, der wie jeder andere .Net-Thread ist. Sie können nicht garantieren, dass er auf einem ausgeführt wird separater Kern oder nicht.
BlueRaja - Danny Pflughoeft
@BlueRaja - Wenn zwei asynchrone Threads gestartet würden, würden beide zur gleichen Zeit ausgeführt, vorausgesetzt, es wären 2 CPU-Kerne vorhanden. Wenn es nur einen gäbe, würde das Betriebssystem planen, wann jeder Thread Priorität erhält und ausgeführt wird, und Ihre typische Single-Thread-Thrash-Situation würde eintreten. So wurde mir beigebracht, wie eine CPU mit Multithreads umgeht.
Ramhound
15

Nein, das Betriebssystem und die CPU entscheiden, was und wann ausgeführt wird. In dem einfachen Beispiel, das Sie gezeigt haben, werden diese Aufgaben unter Ausschluss anderer Aufgaben höchstwahrscheinlich auf separaten Kernen parallel ausgeführt, aber es gibt selten eine Garantie dafür, dass dies der Fall ist.

Mithilfe der Thread-Affinität können Sie versuchen, die Zuordnung eines Kerns zu einem bestimmten Thread zu steuern.

Zusätzlich berücksichtigen Prioritäten Scheduling sollte die Plattform in Bezug auf deren Gewinde vollständig parallel zu stapeln, und welche warten.

Frank Thomas
quelle
1
Ich möchte auch hinzufügen, dass es bei Virtualisierungstechnologien eine andere Schicht zwischen Ihrem Programm und der Hardware gibt. Was das Betriebssystem der Anwendung präsentiert, ist möglicherweise nicht physisch korrekt.
Keltari,
1
Dies sind WinAPI-Funktionen für Betriebssystemthreads, nicht für verwaltete Threads. Sie sollten niemals von C # aus aufgerufen werden, da sie den .Net-Thread-Scheduler ernsthaft stören könnten.
BlueRaja - Danny Pflughoeft