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

11422
developer747

Ich habe einen Pentium-Core-i5-Prozessor mit 4 Kernen. Wenn ich dies in einem C # -Konsolenprogramm mache

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

Sind t1- und t2-Threads garantiert auf separaten Kernen ausgeführt?

21
Assuming that the C# runtime uses equivalent native system calls to spawn another thread (and is thus truly parallel; this is not the case for everything, like CPython's infamous [Global Interpreter Lock](http://en.wikipedia.org/wiki/Global_Interpreter_Lock)), this would depend solely on the operating system's [process/task scheduler](https://en.wikipedia.org/wiki/Scheduling_%28computing%29). In general though, code is truly thread safe if you assume that `t1` and `t2` are executed at different times in an arbitrary order (e.g. it's possible `t2` starts *before* `t1` in some models). Breakthrough vor 11 Jahren 1
Ich wusste nicht, dass es Pentium-i5-Prozessoren gibt. Vielleicht meinten Sie Core i5? Wählerisch. Ich weiß: D JosephGarrone vor 11 Jahren 2

2 Antworten auf die Frage

18
BlueRaja - Danny Pflughoeft

Sie können in .Net nicht garantieren, dass zwei Threadauf zwei separaten Kernen laufen. In der Tat, können Sie auch nicht garantieren, dass man Threadauf nur einen Kern laufen (!) .

Dies ist darauf zurückzuführen, dass verwaltete Threads nicht mit Betriebssystem-Threads identisch sind - ein einziger verwalteter Thread verwendet möglicherweise mehrere Betriebssystem-Threads, um dies zu unterstützen. In C # gehen Sie immer nur direkt mit verwalteten Threads um (zumindest ohne auf p / invoke zurückgreifen zu müssen, um die WinAPI-Threading-Funktionen aufzurufen, die Sie niemals tun sollten) .

Die .Net- und Windows-Thread-Scheduler sind jedoch sehr gut in der Lage, da sie nicht zwei Threads auf einem einzelnen Core ausführen, während ein zweiter Core vollständig inaktiv ist. Im Allgemeinen brauchen Sie sich darum keine Sorgen zu machen.

In der Praxis sind .Net `Thread`s * * OS-Threads. Aber es gibt auch keine Garantie dafür, dass ein einzelner Thread immer auf demselben Core ausgeführt wird. svick vor 11 Jahren 0
@svick: In der Praxis ist das auf x86 ** wahr. Der Standard besagt jedoch ausdrücklich, dass Sie sich nicht auf dieses Verhalten verlassen können. Es könnte sich also in Zukunft ändern. In anderen Versionen der .Net CLR, wie XBox 360, ist es * nicht * wahr. BlueRaja - Danny Pflughoeft vor 11 Jahren 2
@BlueRaja - Die Frage ist konkret, von welcher CLR-Version die Rede ist. Sie können garantieren, dass etwas auf zwei separaten Kernen vorhanden ist, indem Sie asynchrone Threads verwenden, da dies bedeuten würde, dass sie asynchron zueinander laufen würden. Der aktuelle Beispielcode ist technisch gesehen ein Sync-Aufruf. Natürlich entscheidet das Betriebssystem, welche Kerne verwendet werden. Ramhound vor 11 Jahren 0
@Ramhound * "Sie können garantieren, dass etwas auf zwei separaten Kernen vorhanden ist, indem Sie asynchrone Threads verwenden" * - das ist falsch. Das `async`-Schlüsselwort * (von dem Sie annehmen, dass" async-Threads "überflüssig sind) * ist nur ein syntaktischer Zucker für einen` BackgroundWorker`-Thread, der wie jeder andere .Net-Thread ist - Sie können ' t garantiert, ob es auf einem separaten Kern läuft oder nicht. BlueRaja - Danny Pflughoeft vor 11 Jahren 0
@BlueRaja - Wenn zwei asynchrone Threads gestartet wurden, würden sie beide gleichzeitig ausgeführt, vorausgesetzt es waren 2 CPU-Kerne vorhanden. Wenn es nur einen gab, würde das Betriebssystem festlegen, wann jeder Thread Priorität erhalten und ausgeführt werden würde und Ihre typische Thrash-Situation mit einem einzigen Thread auftreten würde. So wurde mir beigebracht, wie eine CPU Multithreads handhabt. Ramhound vor 11 Jahren 0
@ Ramhound: Dein Verständnis ist nahe, aber fehlerhaft. Selbst wenn der Computer über zwei Kerne verfügt, plant das Betriebssystem * nicht notwendigerweise beide Threads auf separate Kerne * (z. B. verwendet es derzeit einen der Kerne für etwas höhere Priorität) *. In diesem Fall würden beide Threads auf denselben Kern terminiert, und der übliche Kontextwechsel würde erfolgen * (was auf jeden Fall geschehen müsste; auf einem normalen PC laufen Dutzende von Prozessen gleichzeitig!) *. Es wird auch nicht "Thrashing" genannt - das ist etwas völlig anderes (http://en.wikipedia.org/wiki/Thrashing_%28computer_science%29). BlueRaja - Danny Pflughoeft vor 11 Jahren 0
@BlueRaja - Sie haben in der Tat recht Thrashing ist etwas anderes, der spezifische Begriff, nach dem ich suche, entgeht mir derzeit. Ich vermute, zwei asynchrone Threads könnten den gleichen Kern erhalten, es fiel mir schwer, die Wörter zu finden, genau zu beschreiben, woran ich denke, und ich werde es einfach fallen lassen. Ramhound vor 11 Jahren 0
15
Frank Thomas

Nein, Betriebssystem und CPU entscheiden, was wann ausgeführt wird. In dem einfachen Beispiel, das Sie gezeigt haben, würden Sie - abgesehen von anderen Aufgaben - höchstwahrscheinlich auf separaten Kernen parallel laufen, aber es gibt nur selten eine Garantie, dass dies der Fall ist.

Sie können die Thread-Affinität verwenden, um zu versuchen, die Zuordnung eines Kerns zu einem bestimmten Thread zu kontrollieren.

Berücksichtigen Sie auch Prioritäten beim Planen des Stapels, um festzulegen, welche Threads vollständig parallel sein sollten und welche warten können.

I also want to add, that with virtualization technologies there is another layer between your program and the hardware. What the OS presents to the application might not be physically accurate. Keltari vor 11 Jahren 1
Those are WinAPI functions for OS threads, not for managed threads. They should never be called from C#, as they could severely interfere with the .Net thread scheduler. BlueRaja - Danny Pflughoeft vor 11 Jahren 1