Wie funktioniert das Vergleichen und Tauschen?

8

Ich habe schon einige Posts gelesen, die sagen, vergleichen und tauschen, Atomizität, aber ich bin immer noch nicht in der Lage zu bekommen, wie es geht ?? Dies ist ein allgemeiner Pseudo-Code für den Vergleich und Swap -

%Vor%

Wie garantiert dies die Atomizität? Zum Beispiel, wenn ich dies verwende, um einen Mutex zu implementieren,

%Vor%

Wie verhindert dies, dass 2 Threads gleichzeitig den Mutex erhalten? Irgendwelche Zeiger würden wirklich geschätzt.

    
knuckle_ball 12.03.2014, 00:18
quelle

2 Antworten

15

"allgemeiner Pseudocode" ist kein tatsächlicher Code der CAS (Compare and Swap) Implementierung. Spezielle Hardware-Anweisungen werden verwendet, um spezielle atomare Hardware in der CPU zu aktivieren. In x86 kann beispielsweise LOCK CMPXCHG verwendet werden ( Ссылка ).

In gcc gibt es zum Beispiel __sync_val_compare_and_swap() builtin - das hardware-spezifische atomare CAS implementiert. Es gibt eine Beschreibung dieser Operation aus einem neuen wunderbaren Buch von Paul E. McKenney ( Is Parallel Schwer programmieren und, wenn ja, was können Sie dagegen tun? , 2014), Abschnitt 4.3 "Atomare Operationen", Seiten 31-32.

Wenn Sie mehr darüber wissen möchten, wie Sie auf atomaren Operationen eine höhere Synchronisation aufbauen und Ihr System vor Spinlocks und brennenden CPU-Zyklen beim aktiven Drehen schützen, können Sie etwas über futex mechanism in Linux lesen. Erste Arbeit über Futex ist Futexes sind knifflig von Ulrich Drepper 2011; der andere ist der LWN-Artikel Ссылка (und der historische ist Fuss, Futexes und Furwocks: Schnelle Userland Locking in Linux , 2002)

Mutex-Sperren, die von Ulrich beschrieben werden, verwenden nur atomare Operationen für "schnellen Pfad" (wenn der Mutex nicht gesperrt ist und unser Thread der einzige ist, der ihn sperren möchte), aber wenn der Mutex gesperrt ist, wird der Thread in den Schlafmodus wechseln Mit futex (FUTEX_WAIT ...) (und es wird die Mutexvariable durch atomare Operation markieren, um den Entriegelungs-Thread über "Es gibt jemanden zu schlafen, der auf diesen Mutex wartet" zu informieren), so dass unlocker weiß, dass er sie mit futex (FUTEX_WAKE) aufwecken muss , ...)

    
osgx 12.03.2014 00:20
quelle
2

Wie verhindert es, dass zwei Threads die Sperre erhalten? Nun, sobald ein Thread erfolgreich ist, wird *mutex 1 sein, daher wird der CAS jedes anderen Threads fehlschlagen (weil er mit dem erwarteten Wert 0 aufgerufen wird). Die Sperre wird aufgehoben, indem 0 in *mutex gespeichert wird.

Beachten Sie, dass dies eine seltsame Verwendung von CAS ist, da es im Wesentlichen eine ABA-Verletzung erfordert. Normalerweise würden Sie einfach einen einfachen atomaren Austausch verwenden:

%Vor%

Oder wenn Sie etwas ausgefeilter sein und Informationen darüber speichern möchten, welcher Thread die Sperre hat, können Sie Tricks mit atomic-fetch-and-add durchführen (siehe zum Beispiel den Linux-Kernel-Spinlock-Code).

    
Kerrek SB 12.03.2014 00:21
quelle