So implementieren Sie Spin Lock mit atomaren C++11-Operationen

Was ist ein Spinlock?

C++-Spin-Lock ist ein Synchronisierungsprimitiv auf niedriger Ebene, das zum Schutz des Zugriffs auf gemeinsam genutzte Ressourcen verwendet wird. Spin Lock ist eine leichte Sperre, die für die kurzfristige Ressourcensperre geeignet ist.

Eigenschaften von Spin-Locks: Wenn ein Thread versucht, einen Spin-Lock zu erhalten, der bereits von einem anderen Thread belegt ist, gerät der Thread in eine Schleife (Spin), in der er kontinuierlich prüft, ob der Lock freigegeben wurde. Wenn die Sperre aufgehoben wurde, kann der Thread die Sperre erwerben und ausführen. Wenn die Sperre noch belegt ist, dreht sich der Thread weiter, bis die Sperre erworben wird.

Ein wichtiges Merkmal einer Spin-Sperre besteht darin, dass sie den Anrufer nicht in den Ruhezustand versetzt. Wenn die Spin-Sperre bereits belegt ist, bleibt der Anrufer in einem beschäftigten Wartezustand, bis die Sperre erworben werden kann. Dies bedeutet, dass Spin-Sperren nur verwendet werden sollten, wenn die Sperrhaltezeit kurz ist und der Thread nicht blockiert wird. Andernfalls wird Prozessorzeit verschwendet und die parallele Leistung von Mehrprozessorsystemen verringert.

In C++ können Spinlocks mithilfe atomarer Operationen und Bedingungsvariablen implementiert werden. C++11 bietet keine dedizierte Schnittstelle zum Implementieren von Spin-Locks, Spin-Locks können jedoch mithilfe atomarer Operationen und Bedingungsvariablen implementiert werden.

Implementierung einer Spin-Sperre mit atomaren C++11-Operationen

C++11 bietet keine dedizierte Schnittstelle zum Implementieren von Spin-Locks, Spin-Locks können jedoch mithilfe atomarer Operationen und Bedingungsvariablen implementiert werden.

Der Beispielcode lautet wie folgt:

#include <mutex>  
#include <atomic>  
  
class spin_lock {  
private:  
    std::atomic_flag flag = { ATOMIC_FLAG_INIT };  
  
public:  
    spin_lock() {}  
  
    void lock() {  
        while (flag.test_and_set(std::memory_order_acquire)) {  
            // spin-wait loop  
        }  
    }  
  
    void unlock() {  
        flag.clear(std::memory_order_release);  
    }  
};

Der Unterschied zwischen Spin-Lock und Mutex-Lock

Spin-Sperren und Mutex-Sperren sind beides Synchronisationsprimitive, die zum Schutz gemeinsam genutzter Ressourcen verwendet werden. Es gibt jedoch einige Unterschiede in ihren Verarbeitungsmethoden und anwendbaren Szenarien.

  • Verarbeitungsmethode: Mutex-Sperren schützen gemeinsam genutzte Ressourcen, indem sie die Ausführung von Threads blockieren. Wenn ein Thread eine Mutex-Sperre erwirbt, werden andere Threads, die versuchen, die Sperre zu erlangen, blockiert, bis der ursprüngliche Inhaber die Sperre aufhebt. Die Spin-Sperre verwendet eine ausgelastete Wartemethode. Wenn ein Thread versucht, die Spin-Sperre zu erhalten, aber fehlschlägt, wird er den Versuch fortsetzen, bis er die Sperre erfolgreich erhält.
  • Overhead: Der Overhead einer Mutex-Sperre ist relativ groß, da für die Verarbeitung von Blockierungs- und Aktivierungsvorgängen ein Wechsel vom Benutzermodus in den Kernelmodus erforderlich ist. Spin-Locks treten im Benutzermodus auf und der Overhead ist relativ gering.
  • Anwendbare Szenarien: Mutex-Sperren eignen sich für Szenarien, in denen die Sperre über einen längeren Zeitraum gehalten wird oder der Thread möglicherweise blockiert wird, z. B. beim Ausführen von E/A-Vorgängen oder beim Verarbeiten komplexer Berechnungen. In diesem Fall verhindert ein Mutex, dass Threads während langer Wartezeiten verhungern. Spin-Sperren eignen sich für Situationen, in denen die Sperrzeit sehr kurz ist und die CPU-Ressourcen nicht knapp sind, z. B. bei kurzfristigem Zugriff auf gemeinsam genutzte Ressourcen oder bei CPU-intensiven Vorgängen. Spin-Sperren können verhindern, dass Threads aufgrund sinnlosen Umschalt- und Planungsaufwands Ressourcen verschwenden.
  • Sperrgranularität: Die Mutex-Sperre hat eine gröbere Granularität und eignet sich zum Schutz des gesamten kritischen Abschnitts oder der gesamten Datenstruktur. Spin-Sperren sind feinkörnig und eignen sich zum Schutz eines kleinen Teils des Codes oder der Datenstruktur in einem kritischen Abschnitt.

Kurz gesagt, Spin-Locks und Mutex-Locks haben ihre eigenen anwendbaren Szenarien, und das entsprechende Synchronisationsprimitiv muss entsprechend der spezifischen Situation ausgewählt werden.

Zusammenfassen

Spin-Locks vermeiden die Prozessplanung und den Thread-Wechsel des Betriebssystems und eignen sich für extrem kurzfristige Situationen. Spin-Locks werden häufig vom Betriebssystemkernel verwendet. Wenn die Spin-Sperre jedoch über einen längeren Zeitraum gesperrt ist, ist sie sehr leistungsintensiv. Je länger der Thread die Sperre hält, desto größer ist das Risiko, dass der Thread, der die Sperre hält, vom Betriebssystem-Scheduler unterbrochen wird. Wenn eine Unterbrechung auftritt, drehen sich andere Threads weiter (und versuchen wiederholt, die Sperre zu erlangen), ohne dass der Thread, der die Sperre hält, die Absicht hat, die Sperre aufzuheben, was zu einer unbestimmten Verzögerung führt, bis der Thread, der die Sperre hält, sie abschließen und freigeben kann.

Supongo que te gusta

Origin blog.csdn.net/renhui1112/article/details/132643639
Recomendado
Clasificación