Antworten:
Wenn Sie reguläre Sperren (Mutexe, kritische Abschnitte usw.) verwenden, versetzt das Betriebssystem Ihren Thread in den Status WAIT und verhindert dies, indem andere Threads auf demselben Kern geplant werden. Dies hat eine Leistungsbeeinträchtigung zur Folge, wenn die Wartezeit sehr kurz ist, da Ihr Thread jetzt auf eine Vorauszahlung warten muss, um die CPU-Zeit erneut zu erhalten.
Außerdem sind Kernelobjekte nicht in jedem Status des Kernels verfügbar, z. B. in einem Interrupt-Handler oder wenn Paging nicht verfügbar ist usw.
Spinlocks verursachen keine Preemption, sondern warten in einer Schleife ("Spin"), bis der andere Kern die Sperre aufhebt. Dies verhindert, dass der Thread sein Quantum verliert und fortgesetzt wird, sobald die Sperre aufgehoben wird. Der einfache Mechanismus von Spinlocks ermöglicht es einem Kernel, ihn in nahezu jedem Zustand zu verwenden.
Aus diesem Grund ist ein Spinlock auf einem Single-Core-Computer einfach ein "Disrupt Interrupts" oder "Raise IRQL", wodurch die Thread-Planung vollständig verhindert wird.
Spinlocks ermöglichen es Kerneln letztendlich, "Big Kernel Lock" (eine Sperre, die beim Eintritt des Kerns in den Kernel und beim Auslösen am Ausgang erhalten wird) zu vermeiden und die Kernel-Grundelemente granular zu sperren, was zu einer besseren Mehrfachverarbeitung auf Mehrkernmaschinen und damit zu einer besseren Leistung führt.
EDIT : Es stellte sich die Frage: "Heißt das, ich sollte Spinlocks verwenden, wo immer dies möglich ist?" und ich werde versuchen, es zu beantworten:
Wie bereits erwähnt, sind Spinlocks nur an Orten nützlich, an denen die erwartete Wartezeit kürzer als ein Quantum ist (sprich: Millisekunden) und die Vorauszahlung wenig sinnvoll ist (z. B. sind Kernelobjekte nicht verfügbar).
Wenn die Wartezeit unbekannt ist oder wenn Sie sich im Benutzermodus befinden, sind Spinlocks nicht effizient. Sie verbrauchen 100% CPU-Zeit auf dem wartenden Kern, während Sie prüfen, ob ein Spinlock verfügbar ist. Sie verhindern, dass andere Threads auf diesem Kern ausgeführt werden, bis Ihr Quantum abläuft. Dieses Szenario ist nur für kurze Bursts auf Kernel-Ebene möglich und für eine Anwendung im Benutzermodus unwahrscheinlich.
Hier ist eine Frage zu SO, die sich damit befasst: Spinlocks, wie nützlich sind sie?
Angenommen, eine Ressource ist durch eine Sperre geschützt. Ein Thread, der Zugriff auf die Ressource wünscht, muss zuerst die Sperre erwerben. Wenn die Sperre nicht verfügbar ist, überprüft der Thread möglicherweise wiederholt, ob die Sperre freigegeben wurde. Während dieser Zeit wartet der besetzte Thread, sucht nach der Sperre, verwendet die CPU, erledigt aber keine nützliche Arbeit. Eine solche Sperre wird als Spin-Sperre bezeichnet.
Es ist eine Schleife, die so lange weitergeht, bis eine bestimmte Bedingung erfüllt ist:
while(cantGoOn) {};
sleep(0)
, würde es den Thread verhindern und den Zweck der Verwendung eines Spinlocks in erster Linie zunichte machen . Wenn Sie anderen Threads nachgeben müssen, sollten Sie eine reguläre Sperre verwenden. (Ich weiß, dass Ihr Kommentar sehr alt ist, wollte aber verhindern, dass andere dies als Vorschlag sehen).
while(something != TRUE ){};
// it happend
move_on();
Es ist eine Art Schloss, das beschäftigt ist zu warten
Es wird als Anti-Pattern angesehen, mit Ausnahme der Treiberprogrammierung auf sehr niedriger Ebene (wo es vorkommen kann, dass das Aufrufen einer "richtigen" Wartefunktion mehr Overhead hat als nur das Sperren für einige Zyklen).
Siehe zum Beispiel Spinlocks im Linux-Kernel .
SpinLocks sind diejenigen, in denen der Thread wartet, bis die Sperre verfügbar ist. Dies wird normalerweise verwendet, um den Aufwand für das Abrufen der Kernelobjekte zu vermeiden, wenn das Kernelobjekt innerhalb eines kurzen Zeitraums erfasst werden kann.
Ex:
While(SpinCount-- && Kernel Object is not free)
{}
try acquiring Kernel object
Sie möchten einen Spinlock verwenden, wenn Sie der Meinung sind, dass es billiger ist, in eine belebte Warteschleife einzutreten und eine Ressource zu bündeln, anstatt sie zu blockieren, wenn die Ressource gesperrt ist.
Das Drehen kann vorteilhaft sein, wenn Sperren feinkörnig und zahlreich sind (z. B. eine Sperre pro Knoten in einer verknüpften Liste) sowie wenn die Haltezeiten für Sperren immer extrem kurz sind. Im Allgemeinen sollte man beim Halten einer Spin-Sperre vermeiden, zu blockieren, alles aufzurufen, was selbst blockieren könnte, mehr als eine Spin-Sperre gleichzeitig zu halten, dynamisch verteilte Anrufe (Schnittstelle und Virtuals) zu tätigen und statisch verteilte Anrufe in einen Code zu tätigen, den man nicht tut. ' t besitzen oder Speicher zuweisen.
Es ist auch wichtig zu beachten, dass SpinLock aus Leistungsgründen ein Werttyp ist. Daher muss man sehr vorsichtig sein, um eine SpinLock-Instanz nicht versehentlich zu kopieren, da die beiden Instanzen (das Original und die Kopie) dann völlig unabhängig voneinander wären, was wahrscheinlich zu einem fehlerhaften Verhalten der Anwendung führen würde. Wenn eine SpinLock-Instanz weitergegeben werden muss, sollte sie als Referenz und nicht als Wert übergeben werden.
Kurz gesagt, Spinlock verwendet Atomic Compare and Swap (CAS) oder Test-and-Set-ähnliche Anweisungen, um eine sperrenfreie, wartefreie, thread-sichere Sprache zu implementieren. Solche Strukturen lassen sich in Mehrkernmaschinen gut skalieren.
Ja, der Punkt bei Spin-Locks (im Vergleich zu herkömmlichen kritischen Abschnitten usw.) ist, dass sie unter bestimmten Umständen eine bessere Leistung bieten (Multicore-Systeme ..), da sie nicht sofort den Rest des Thread-Quantums liefern.
Spinlock ist eine Art Schloss, das nicht blockierbar und nicht schlaffähig ist. Jeder Thread, der einen Spinlock für eine gemeinsam genutzte oder kritische Ressource erwerben möchte, dreht sich kontinuierlich und verschwendet den CPU-Verarbeitungszyklus, bis er die Sperre für die angegebene Ressource erhält. Sobald Spinlock erworben wurde, versucht es, die Arbeit in seinem Quantum abzuschließen und dann die Ressource freizugeben. Spinlock ist die Art von Sperre mit der höchsten Priorität. Man kann einfach sagen, dass es sich um eine nicht präventive Art von Sperre handelt.