Schlösser in der Warteschlange

In die Warteschlange eingereihte Drehsperren sind eine Variante von Drehsperren , die für hochgekämte Sperren gut funktionieren. Herkömmliche, nicht queuierte Drehsperren sind eine bessere Wahl für leicht angehaltene oder kürzere Dauer sperren.

Zu den Vorteilen der Verwendung einer in die Warteschlange eingereihten Drehsperre gehören:

  1. Reduzierte Prozessorverknügung: Herkömmliche Drehsperren können zu erheblichen Prozessorkonflikten führen, wenn mehrere Threads versuchen, die Sperre gleichzeitig abzurufen, da sie den Sperrstatus kontinuierlich durchlaufen (oder "drehen") überprüfen. Dies kann die Systemleistung beeinträchtigen, insbesondere auf Multiprozessorsystemen. Durch das Organisieren von Threads in einer Warteschlange in eine Warteschlange verringern Sie dies durch Sperre in der Warteschlange. Wenn ein Thread eine Sperre erwirbt, dreht sich nur die nächste Zeile aktiv, und wartet darauf, die Sperre zu erwerben. Dies reduziert die CPU-Zyklen, die beim Drehen verschwendet werden, insbesondere, wenn die Sperre länger gehalten wird.

  2. Fairness und Vermeidung von Starvation: Eines der Probleme mit grundlegenden Spin-Sperren ist das Fehlen von Fairness; ein Thread kann gehungert werden und nie die Sperre erwerben, wenn andere Threads kontinuierlich erwerben und freigeben. In die Warteschlange eingereihte Drehsperren adressieren dies, indem sichergestellt wird, dass Threads die Sperre in der Reihenfolge abrufen, an der sie versucht haben. Diese sequenzielle Behandlung verhindert Starvation und stellt sicher, dass alle Threads im Laufe der Zeit gewartet werden.

  3. Skalierbarkeit: Da sich die Anzahl der Prozessoren oder Kerne in einem System erhöht, wird die Effizienz der Synchronisierungsmechanismen für die Leistung entscheidend. Schlösser in der Warteschlange sind skalierbarer als herkömmliche Drehsperren, da sie den Aufwand für die Prozessoren verringern, indem die aktive Drehung über alle Kerne minimiert wird. Dies ist besonders wichtig für hochleistungsfähige Multikernsysteme, bei denen sich die Treibereffizienz direkt auf die Gesamtleistung des Systems auswirken kann.

  4. Effizienter Einsatz von Systemressourcen: Durch die Reduzierung unnötiger Prozessordrehungen ermöglichen in der Warteschlange eingereihte Drehsperren die Nutzung ihrer Ressourcen effizienter. Dies verbessert nicht nur die Leistung des Gerätetreibers, sondern wirkt sich auch positiv auf die Gesamtreaktionsfähigkeit und den Stromverbrauch des Systems aus, was insbesondere in leistungsempfindlichen Umgebungen von Vorteil ist.

  5. Einfachheit und Zuverlässigkeit: Trotz ihrer Vorteile bei der Reduzierung der Inhalte und der Verbesserung der Fairness abstrahiert das in der Warteschlange eingereihte Spin lockt die Komplexität vom Entwickler ab. Sie bieten einen einfachen und zuverlässigen Mechanismus zum Schutz freigegebener Ressourcen, ohne dass der Entwickler komplexe Sperrlogik implementieren muss. Diese Einfachheit reduziert die Wahrscheinlichkeit von Fehlern im Zusammenhang mit unsachgemäßer Sperrbehandlung, wodurch die Zuverlässigkeit des Treibers verbessert wird.

Im Folgenden finden Sie einen vereinfachten Codeausschnitt, der die beschriebenen Vorgänge mit einer Warteschlange-Drehsperre in einem Windows-Kernelmodustreiber veranschaulicht. In diesem Beispiel wird gezeigt, wie Sie eine Drehsperre mithilfe von KeInitializeSpinLock deklarieren und initialisieren. Anschließend wird die Sperre mithilfe von KeAcquireInStackQueuedSpinLock und KeReleaseInStackQueuedSpinLock bzw. KeReleaseInStackQueuedSpinLock erworben und freigegeben.

KSPIN_LOCK SpinLock;  
KLOCK_QUEUE_HANDLE LockHandle;  

// Initialize the spin lock  
KeInitializeSpinLock(&SpinLock);  

// Assume this function is called in some kind of context where   
// the below operations make sense, e.g., in a device I/O path  

// Acquire the queued spin lock  
KeAcquireInStackQueuedSpinLock(&SpinLock, &LockHandle);  

// At this point, the current thread holds the spin lock.  
// Perform thread-safe operations here.  
    
// ...  

// Release the queued spin lock  
KeReleaseInStackQueuedSpinLock(&LockHandle);  

Der Treiber weist eine KLOCK_QUEUE_HANDLE Struktur zu, die vom Zeiger an KeAcquireInStackQueuedSpinLock übergeben wird. Der Treiber übergibt dieselbe Struktur durch Zeiger auf KeReleaseInStackQueuedSpinLock , wenn er die Drehsperre loslässt.

Treiber sollten normalerweise die Struktur auf dem Stapel jedes Mal zuordnen, wenn sie die Sperre erwerben. Ein Treiber sollte die Struktur nicht als Teil des Gerätekontexts zuordnen und dann dieselbe Struktur aus mehreren Threads teilen.

Treiber dürfen keine Aufrufe an die in die Warteschlange eingereihten Spin-Lock-Routinen und die normalen KeXxxSpinLock-Routinen auf derselben Drehsperre mischen.

Wenn sich der Treiber bereits bei IRQL = DISPATCH_LEVEL befindet, kann er stattdessen KeAcquireInStackQueuedSpinLockAtDpcLevel und KeReleaseInStackQueuedSpinLockFromDpcLevel aufrufen.