GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Warum sind Spin-Locks eine gute Wahl im Linux-Kernel-Design anstelle von etwas, das im Userland-Code häufiger vorkommt, wie Semaphor oder Mutex?

Da die Frage impliziert, dass Spinlocks eine "Verschwendung" sind, sollten Spinlocks nur kurz gehalten werden.

Spinlocks sind nicht die einzige Möglichkeit, mehrere Threads zu synchronisieren. Mutexe/Semaphore werden auch im Linux-Kernel verwendet, ebenso wie andere Synchronisationsprimitive (z. B. Warteschlangen, Ereignisse).

Der Kernel muss sich jedoch mit Fällen befassen, die der Userspace nie sieht, ein häufiger Fall sind Interrupt-Handler. Interrupt-Handler können unter Linux nicht neu geplant werden, müssen aber oft einige Synchronisierungs-Primitive verwenden (z. B. um ein Arbeitselement zu einer verknüpften Liste hinzuzufügen, die ein anderer Thread weiter verarbeitet). Da Interrupt-Handler nicht schlafen können, können sie keine Mutexe, Warteschlangen usw. verwenden. Das lässt ziemlich viele Spinlocks übrig. Wenn ein Thread den Zugriff mit einem Interrupt-Handler synchronisieren muss, muss er auch denselben Spinlock verwenden.

Spinlocks sind nicht unbedingt eine Verschwendung. Sie sind für den Non-Contention/Non-Waiting-Case optimiert und können sehr schnell genommen und freigegeben werden. In diesem Fall sind sie schneller und erfordern weniger Overhead als andere Synchronisationsprimitive.


Die Wahl zwischen einem Spinlock und einem anderen Konstrukt, das den Aufrufer dazu veranlasst, eine CPU zu blockieren und die Kontrolle über eine CPU abzugeben, wird zu einem großen Teil von der Zeit bestimmt, die zum Ausführen eines Kontextwechsels benötigt wird (Speichern von Registern/Zustand im Sperrthread und Wiederherstellen von Registern/Zustand in einem anderen Thread). Der Zeitaufwand und auch die Cache-Kosten dafür können erheblich sein.

Wenn ein Spinlock verwendet wird, um den Zugriff auf Hardwareregister oder ähnliches zu schützen, wo jeder andere Thread, der darauf zugreift, nur eine Frage von Millisekunden oder weniger benötigt, bevor er die Sperre freigibt, dann ist es eine viel bessere Nutzung der CPU-Zeit, um zu warten anstatt den Kontext zu wechseln und weiterzumachen.


Andere haben geantwortet. Ich werde die Fälle zusammenfassen, in denen Sie Spinlock und Regeln verwenden würden, um Spinlock zu verwenden.

1. Wann wird Spinlock verwendet?

Antwort:In den folgenden Situationen.

  1. Der Thread, der die Sperre hält, darf nicht schlafen.
  2. Der Thread, der auf eine Sperre wartet, schläft nicht, sondern dreht sich in einer engen Schleife.

Bei richtiger Anwendung kann Spinlock eine höhere Leistung erbringen als Semaphore. Beispiel:Interrupt-Handler.

2. Welche Regeln gelten für die Verwendung von Spinlocks?

Antwort:

Regel - 1:Jeder Code, der den Spinlock hält, kann den Prozessor aus keinem Grund verlassen, außer um Interrupts zu bedienen (manchmal nicht einmal dann). Code mit Spinlock kann also nicht schlafen.

Grund:Angenommen, Ihr Treiber, der Spinlock hält, geht schlafen. Beispiel:Ruft die Funktion copy_from_user() auf oder copy_to_user() , oder die Kernel-Preemption tritt ein, sodass der Prozess mit höherer Priorität Ihren Code beiseite schiebt. Tatsächlich gibt der Prozess die CPU auf, die Spinlock hält.

Jetzt wissen wir nicht, wann der Code die Sperre freigibt. Wenn ein anderer Thread versucht, dieselbe Sperre zu erhalten, würde er sich sehr lange drehen. Im schlimmsten Fall würde dies zu einer Deedlock führen.

Der Kernel-Preemption-Fall wird vom Spinlock-Code selbst behandelt. Jedes Mal, wenn der Kernelcode einen Spinlock enthält, wird die Präemption auf dem entsprechenden Prozessor deaktiviert. Sogar Einprozessorsysteme müssen die Präemption auf diese Weise deaktivieren.

Regel - 2:Deaktiviere Interrupts auf der lokalen CPU, während der Spinlock gehalten wird.

Grund:Unterstützen Sie Ihren Treiber mit einem Spinlock, das den Zugriff auf das Gerät steuert und dann einen Interrupt ausgibt. Dies bewirkt, dass der Interrupt-Handler ausgeführt wird. Jetzt benötigt auch der Interrupt-Handler die Sperre, um auf das Gerät zuzugreifen. Wenn der Interrupt-Handler auf demselben Prozessor läuft, beginnt er sich zu drehen. Der Treibercode kann auch nicht ausgeführt werden, um die Sperre freizugeben. SO dreht sich der Prozessor für immer.

Regel - 3:Spinlocks müssen so kurz wie möglich gehalten werden.

Grund:Lange Lock-Hold-Zeiten hindern auch den aktuellen Prozessor am Scheduling, was bedeutet, dass ein Prozess mit höherer Priorität möglicherweise warten muss, um die CPU zu erhalten.

Daher wirkt es sich auf die Kernel-Latenz aus (Zeit, die ein Prozess möglicherweise warten muss, um geplant zu werden). Typischerweise sollten Spinlocks für die Zeitdauer gehalten werden, weniger als die CPU benötigt, um einen Kontextwechsel zwischen Threads durchzuführen.

Regel -4:Wenn Sie Semaphore und Spinlocks haben, müssen beide genommen werden. Dann nehmen Sie zuerst Semaphor und dann Spinlock.


Linux
  1. Linux – Warum zeigt Linux sowohl mehr als auch weniger Speicher an, als ich physisch installiert habe?

  2. Linux – Warum kann der Kernel Init nicht ausführen?

  3. Linux – Proprietäre oder geschlossene Teile des Kernels?

  4. Linux – Sind verschiedene Linux/Unix-Kernel austauschbar?

  5. Was sind Bash-Exit-Codes in Linux

Warum ich unter Linux exa anstelle von ls verwende

Linux vs. Mac OS:15 Gründe, warum Sie Linux anstelle von Mac OS verwenden sollten

6 Gründe, warum Linux nicht mehr Apps hat

Warum denken manche Leute, dass Linux-Rechnerkonten mit Passwörtern sicherer sind als Konten ohne Passwörter?

Warum ist das Zerreißen von Videos unter Linux ein solches Problem?

Warum unterscheiden sich Linux-Systemrufnummern in x86 und x86_64?