Wann genau geht .NET Monitor in den Kernel-Modus?

8

Ich möchte eine Liste aller möglichen Bedingungen kompilieren, die Monitor in den Kernelmodus bringen / Kernel-Sync-Objekt verwenden.

Der Sync-Block hat ein Feld, um auf das Kernel-Objekt zu verweisen, daher habe ich daraus abgeleitet, dass lock irgendwann in den Kernel-Modus wechselt.

Ich fand das: Lock (Monitor) interne Implementierung in .NET

Aber es gibt zu viele Fragen, die beantwortet werden müssen, und die einzige nützliche Information ist, dass das OP seine eigene Frage beantwortet hat, indem es einfach gesagt hat, dass die lock irgendwann in den Kernel-Modus gehen wird. Auch gibt es keine Links zu irgendetwas, um diese Antwort zu unterstützen.

Meine Frage ist anders - Ich möchte wissen, wann genau lock in den Kernel-Modus geht (nicht wenn und nicht warum - wann).

Ich bin mehr interessiert an .NET 4 und 4.5, wenn es einen Unterschied zu älteren Versionen gibt

BEARBEITEN: Aus dem Richter-Buch: "Ein Synchronisierungsblock enthält Felder für ein Kernel-Objekt, die ID des besitzenden Threads, eine Rekursionsanzahl und eine Anzahl wartender Threads."

    
Boppity Bop 17.02.2013, 15:04
quelle

3 Antworten

19

Die meisten dieser Fragen können beantwortet werden, indem man sich den CLR-Quellcode anschaut, der über die SSCLI20 Verteilung . Es wird ziemlich alt, es ist .NET 2.0 Vintage, aber eine Menge der CLR-Kernfunktionen haben sich nicht viel verändert.

Die Quellcodedatei, die Sie betrachten möchten, ist clr / src / vm / syncblk.cpp. Drei Klassen spielen dabei eine Rolle: AwareLock ist die Low-Level-Sperrimplementierung, die für die Erfassung der Sperre zuständig ist, SyncBlock ist die Klasse, die die Warteschlange von Threads implementiert, die auf eine Sperre warten, CLREvent ist der Wrapper für die Betriebssystemsynchronisierung Objekt, nach dem du fragst.

Das ist C ++ - Code und die Abstraktionsstufe ist ziemlich hoch, dieser Code interagiert stark mit dem Garbage Collector und es ist eine Menge Testcode enthalten. Also werde ich eine kurze Beschreibung des Prozesses geben.

SyncBlock hat das Mitglied m_Monitor, in dem die AwareLock-Instanz gespeichert ist. SyncBlock :: Enter () ruft AwareLock :: Enter () direkt auf. Es versucht zuerst, das Schloss so billig wie möglich zu erwerben. Überprüfen Sie zuerst, ob der Thread die Sperre bereits besitzt und erhöhen Sie die Sperrzahl, wenn dies der Fall ist. Verwenden Sie als Nächstes FastInterlockCompareExchange (), eine interne Funktion, die Interlocked.CompareExchange () sehr ähnlich ist. Wenn die Sperre nicht ausgeführt wird, ist dies sehr schnell erfolgreich und Monitor.Enter () gibt zurück. Wenn nicht, dann besitzt bereits ein anderer Thread die Sperre, AwareLock :: EnterEpilog wird verwendet. Der Thread-Scheduler des Betriebssystems muss eingebunden werden, damit CLREvent verwendet wird. Es wird bei Bedarf dynamisch erstellt und die WaitOne () -Methode aufgerufen. Das wird einen Kernel-Übergang beinhalten.

Also genug, um Ihre Frage zu beantworten: Die Monitor-Klasse tritt in den Kernel-Modus ein, wenn die Sperre besteht und der Thread warten muss.

    
Hans Passant 17.02.2013, 17:09
quelle
2
___ qstnhdr ___ Wann genau geht .NET Monitor in den Kernel-Modus? ___ qstntxt ___

Ich möchte eine Liste aller möglichen Bedingungen kompilieren, die Monitor in den Kernelmodus bringen / Kernel-Sync-Objekt verwenden.

Der Sync-Block hat ein Feld, um auf das Kernel-Objekt zu verweisen, daher habe ich daraus abgeleitet, dass %code% irgendwann in den Kernel-Modus wechselt.

Ich fand das: Lock (Monitor) interne Implementierung in .NET

Aber es gibt zu viele Fragen, die beantwortet werden müssen, und die einzige nützliche Information ist, dass das OP seine eigene Frage beantwortet hat, indem es einfach gesagt hat, dass die %code% irgendwann in den Kernel-Modus gehen wird. Auch gibt es keine Links zu irgendetwas, um diese Antwort zu unterstützen.

Meine Frage ist anders - Ich möchte wissen, wann genau %code% in den Kernel-Modus geht (nicht wenn und nicht warum - wann).

Ich bin mehr interessiert an .NET 4 und 4.5, wenn es einen Unterschied zu älteren Versionen gibt

BEARBEITEN: Aus dem Richter-Buch: "Ein Synchronisierungsblock enthält Felder für ein Kernel-Objekt, die ID des besitzenden Threads, eine Rekursionsanzahl und eine Anzahl wartender Threads."

    
___ tag123net ___ Das .NET-Framework ist ein Software-Framework, das hauptsächlich für das Microsoft Windows-Betriebssystem entwickelt wurde. Es enthält eine Implementierung der Basisklassenbibliothek, Common Language Runtime (allgemein als CLR bezeichnet), Common Type System (allgemein als CTS bezeichnet) und Dynamic Language Runtime. Es unterstützt viele Programmiersprachen, einschließlich C #, VB.NET, F # und C ++ / CLI. NICHT für Fragen zu .NET Core verwenden. ___ answer14923685 ___

Die meisten dieser Fragen können beantwortet werden, indem man sich den CLR-Quellcode anschaut, der über die SSCLI20 Verteilung . Es wird ziemlich alt, es ist .NET 2.0 Vintage, aber eine Menge der CLR-Kernfunktionen haben sich nicht viel verändert.

Die Quellcodedatei, die Sie betrachten möchten, ist clr / src / vm / syncblk.cpp. Drei Klassen spielen dabei eine Rolle: AwareLock ist die Low-Level-Sperrimplementierung, die für die Erfassung der Sperre zuständig ist, SyncBlock ist die Klasse, die die Warteschlange von Threads implementiert, die auf eine Sperre warten, CLREvent ist der Wrapper für die Betriebssystemsynchronisierung Objekt, nach dem du fragst.

Das ist C ++ - Code und die Abstraktionsstufe ist ziemlich hoch, dieser Code interagiert stark mit dem Garbage Collector und es ist eine Menge Testcode enthalten. Also werde ich eine kurze Beschreibung des Prozesses geben.

SyncBlock hat das Mitglied m_Monitor, in dem die AwareLock-Instanz gespeichert ist. SyncBlock :: Enter () ruft AwareLock :: Enter () direkt auf. Es versucht zuerst, das Schloss so billig wie möglich zu erwerben. Überprüfen Sie zuerst, ob der Thread die Sperre bereits besitzt und erhöhen Sie die Sperrzahl, wenn dies der Fall ist. Verwenden Sie als Nächstes FastInterlockCompareExchange (), eine interne Funktion, die Interlocked.CompareExchange () sehr ähnlich ist. Wenn die Sperre nicht ausgeführt wird, ist dies sehr schnell erfolgreich und Monitor.Enter () gibt zurück. Wenn nicht, dann besitzt bereits ein anderer Thread die Sperre, AwareLock :: EnterEpilog wird verwendet. Der Thread-Scheduler des Betriebssystems muss eingebunden werden, damit CLREvent verwendet wird. Es wird bei Bedarf dynamisch erstellt und die WaitOne () -Methode aufgerufen. Das wird einen Kernel-Übergang beinhalten.

Also genug, um Ihre Frage zu beantworten: Die Monitor-Klasse tritt in den Kernel-Modus ein, wenn die Sperre besteht und der Thread warten muss.

    
___ tag123multithreading ___ Multi-Threading ist die Fähigkeit eines Computers oder eines Programms, Arbeit gleichzeitig oder asynchron auszuführen, indem mehrere gleichzeitige Ausführungsströme (im Allgemeinen als Threads bezeichnet) verwendet werden. ___ tag123c ___ C # (sprich "Cis") ist eine objektorientierte Programmiersprache auf hohem Niveau, die für die Erstellung einer Vielzahl von Anwendungen entwickelt wurde, die auf dem .NET Framework (oder .NET Core) ausgeführt werden. C # ist einfach, leistungsfähig, typsicher und objektorientiert. ___ tag123net40 ___ Version 4.0 von .NET Framework. Verwenden Sie für Fragen speziell zu .NET Framework 4.0. Bei Fragen zu .NET Framework verwenden Sie im Allgemeinen das .net-Tag. ___ tag123net45 ___ Version 4.5 des Microsoft .NET Framework. Verwenden Sie diese Option für Fragen, die sich speziell auf .NET Framework 4.5 beziehen. Bei Fragen zu .NET Framework verwenden Sie im Allgemeinen das .net-Tag. ___ answer 14923379 ___

Wenn das Schloss stark beansprucht wird.

Wenn die Sperre schwach ist, gibt es einen schnellen CPU-Spinlock, um darauf zu warten, dass die Sperre wieder frei ist, aber wenn dieser nicht lange genug wartet, dass die Sperre frei ist, blockiert der Thread den Mutex Dies beinhaltet einen Aufruf im Kernelmodus, um den Thread und andere solche Verwaltungsaufgaben zu unterbrechen.

    
___ answer14922692 ___

Nach dem Spinwait-Schritt.

zusätzliche Intelligenz kann vorhanden sein, wie zum Beispiel das Überspringen von Spinwait auf Einzelkernmaschinen, da die umkämpfte Sperre erst nach Freigabe des Threads freigegeben werden konnte.

    
___
Puppy 17.02.2013 16:37
quelle
1

Nach dem Spinwait-Schritt.

zusätzliche Intelligenz kann vorhanden sein, wie zum Beispiel das Überspringen von Spinwait auf Einzelkernmaschinen, da die umkämpfte Sperre erst nach Freigabe des Threads freigegeben werden konnte.

    
Andrew Arnott 17.02.2013 15:27
quelle