Heim > System-Tutorial > LINUX > Als Embedded-Entwicklungsingenieur müssen Sie den Synchronisierungsmechanismus des Linux-Kernels kennen.

Als Embedded-Entwicklungsingenieur müssen Sie den Synchronisierungsmechanismus des Linux-Kernels kennen.

王林
Freigeben: 2024-02-12 14:50:07
nach vorne
1290 Leute haben es durchsucht

作为嵌入式开发工程师,关于Linux kernel同步机制你不得不知道

Vorwort

Synchronisation ist die Interaktion zwischen Prozessen sowie zwischen Prozessen und Systemressourcen. Da der Linux-Kernel Multitasking verwendet, muss es einen Synchronisationsmechanismus zwischen mehreren Prozessen geben, um die Koordination sicherzustellen.

Es gibt viele Synchronisierungsmechanismen im Linux-Kernel. Heute konzentrieren wir uns auf die asynchronen und synchronen Mechanismen im Kernel und konzentrieren uns dabei auf den asynchronen Mechanismus im Kernel. Der asynchrone Mechanismus im Kernel ist in zwei Typen unterteilt: Der eine ist der Synchronisationsmechanismus der Anwendungsschicht, dh die Kommunikation zwischen Threads der Anwendungsschicht, der andere ist der Synchronisationsmechanismus des Kernels.

Wenn ein Thread in den Kernel-Status wechselt, kann er direkt mit dem Kernel kommunizieren. Es gibt zwei Threads im Kernel: Einer ist Thread A. Nachdem er in den Kernel-Status eingetreten ist, kommuniziert er direkt mit dem Kernel und teilt ihm mit, was zu tun ist. Wenn er abgeschlossen ist, benachrichtigt er den Kernel. (Wir nennen diese Operation semi) Wenn ein Thread in den Kernel-Status eintritt, kommuniziert er zunächst einmal mit dem Kernel und kann dann direkt ausgeführt werden.

Der Synchronisationsmechanismus im Kernel ist im Wesentlichen ein Kommunikationsmechanismus zwischen Threads, und die Kommunikation zwischen ihnen wird durch den Synchronisationsmechanismus erreicht.

1. Kommunikation zwischen Prozessen

Um die Korrektheit und Konsistenz des Systems sicherzustellen, verwendet der Linux-Kernel Blockierungswarteschlangen, um die Kommunikation zwischen Prozessen während der Kommunikation zwischen Prozessen abzuwickeln. Eine blockierende Warteschlange bedeutet, dass beim Senden einer Nachricht ein Element in der Nachrichtenwarteschlange erstellt wird, aber nicht alle Nachrichten gesendet werden. Erst wenn die Warteschlange für eine bestimmte Nachricht voll ist, wird sie gesendet. Befindet sich keine Nachricht in der Warteschlange des Empfängers, wird die Benachrichtigung empfangen. Befindet sich eine Nachricht in der Warteschlange des Empfängers, wird keine Benachrichtigung empfangen.

Im Kernel ist die Blockierungswarteschlange abstrahiert, d. h. wenn ein Prozess eine Nachricht sendet, wird diese blockiert. Daher ist die Blockierungswarteschlange eigentlich ein Synchronisationsmechanismus. Die Blockierungswarteschlange erstellt über eine bestimmte Funktion ein neues Objekt, das einen Warteschlangenzeiger (Push/Pop) enthält. Wenn die Warteschlange voll ist, verwendet das System das Objekt, auf das der Warteschlangenzeiger zeigt, als Thread des ersten Prozesses, der eine Benachrichtigung ausgibt. Das heißt, der Prozess wird benachrichtigt, bevor er seine Aufgaben weiter ausführen kann.

2. Semaphor

Semaphoren können zum Senden oder Empfangen von Nachrichten verwendet werden. Wenn ein Prozess ein Semaphor besitzt, bedeutet das, dass er bereits ein eigenes Semaphor besitzt, bei dem es sich um eine eigene private Variable handelt. Diese private Variable kann nicht von anderen Prozessen abgerufen werden. Semaphore werden verwendet, um die Anzahl der Semaphore darzustellen, die einem Prozess gehören. Wenn dieser Prozess der Besitzer des Semaphors ist, kann er Nachrichten an andere Prozesse senden. Diese private Variable darf nur von diesem Prozess selbst verwendet werden und kann nicht auf die Prozesse anderer Prozesse übertragen werden.

Wenn ein Thread über ein eigenes Semaphor verfügt, kann er über gemeinsam genutzte Variablen mit anderen Threads kommunizieren. Gemeinsam genutzte Variablen werden auch in anderen Threads verwendet, und andere Threads verwenden gemeinsam genutzte Variablen, um mit sich selbst zu kommunizieren.

3. Mutex

Mutex ist hauptsächlich für Systemressourcen gedacht. Mutexe im Linux-Kernel können in zwei Typen unterteilt werden: gemeinsam genutzte Ressourcen und globale Mutex-Ressourcen.

Gemeinsame Ressourcen werden von Prozessen gemeinsam genutzt. Wenn ein Prozess beispielsweise mehrere Threads hat, kann jeder Thread auf diesen gemeinsam genutzten Speicherbereich zugreifen. Globale, sich gegenseitig ausschließende Ressourcen bedeuten, dass Prozesse und Threads nur auf den globalen Speicherbereich zugreifen können, in dem sie sich befinden. In einem System können Mutexe verwendet werden, um die gleichzeitige Ausführung mehrerer Prozesse im Speicher zu ermöglichen. Wenn Sie jedoch die gleichzeitige Ausführung mehrerer Prozesse implementieren möchten, müssen Sie einen Synchronisierungsmechanismus verwenden, um sicherzustellen, dass alle Prozesse im selben Speicher ausgeführt werden können. Mithilfe eines Mutex kann ein Prozess nur auf den globalen Speicherbereich zugreifen, in dem er sich befindet, nicht jedoch auf andere Speicherbereiche. Ein Mutex hat jedoch einen großen Vorteil, nämlich dass es zu keiner Prozessblockierung kommt.

4. Nachrichtenwarteschlange

Das Aufkommen von Nachrichtenwarteschlangen hat die Kommunikation zwischen Prozessen erheblich erweitert. Im Kernel gibt es zusätzlich zum Synchronisationsmechanismus einen weiteren asynchronen Mechanismus, nämlich die Nachrichtenwarteschlange. Wir alle wissen, dass der Linux-Kernel Nachrichtenwarteschlangen unterstützt. Obwohl der Kernel detaillierte Informationen zu Nachrichtenwarteschlangen enthält, müssen wir dennoch mit der Anwendungsschicht beginnen, um Nachrichtenwarteschlangen zu verstehen, da der Kernel keine Nachrichtenwarteschlangen im Benutzermodus unterstützt.

Lassen Sie uns zunächst verstehen, was eine Nachrichtenwarteschlange ist.

Die Nachrichtenwarteschlange ist eine spezielle Warteschlange, die die Synchronisierungsanforderungen zwischen mehreren Anwendungsthreads erfüllen kann. Nachrichtenwarteschlangen werden verwendet, um eine asynchrone Kommunikation zwischen Anwendungen und anderen Prozessen oder Threads bereitzustellen. Wenn wir asynchron kommunizieren müssen, können wir dies über eine Nachrichtenwarteschlange tun. Wenn wir beispielsweise die Funktion clear() aufrufen, können wir direkt eine registrierte Nachrichtenwarteschlange verwenden.

Wie erstellt man also eine Nachrichtenwarteschlange? Wenn wir ext2.json verwenden, können wir mit dem Semaphore-Befehl in JAR.json.clear() eine Nachrichtenwarteschlange erstellen.

5. Geteiltes Gedächtnis

Im Shared Memory verwenden wir Shared Locks, aber da Shared Locks den Speicher mit einem bestimmten Prozess teilen, müssen Sie eine Shared Lock von anderen Prozessen anfordern, wenn Sie sie erwerben möchten.

Wie im obigen Beispiel greifen wir über das Schlüsselwort volatile auf den gemeinsamen Speicher zu. Zu diesem Zeitpunkt stellen Sie keine Anfragen von anderen Prozessen. Wenn Sie also diese gemeinsame Sperre erhalten möchten, müssen Sie nur Anfragen von anderen Prozessen anfordern. Dadurch wird eine Konkurrenz zwischen den beiden Prozessen vermieden und eine Datensynchronisation erreicht.

Da eine gemeinsame Sperre den Speicher mit einem Prozess teilt, müssen Sie den Prozess auffordern, auf seine Adresse zuzugreifen. Die einfachste Lösung für diese Situation ist die Verwendung eines Thread-Pools.

Im Thread-Pool gibt es ein Objekt namens „Byte“, bei dem es sich auch um eine gemeinsam genutzte Sperre handelt. Wenn Sie diese Sperre erhalten möchten, müssen Sie lediglich eine Anfrage an das Byte-Objekt senden. Zu diesem Zeitpunkt sendet das Byte-Objekt Ihre Anfrage an die Warteschlange des Threads. Wenn der Thread die Anfrage empfängt, sendet er eine Antwortnachricht an Sie zurück.

6. Thread-Pool

Thread-Pool ist ein sehr gutes Thread-Management-Tool. Es ermöglicht die gleichzeitige Ausführung mehrerer Threads und kann außerdem Deadlocks und Konflikte zwischen Threads reduzieren. Eine seiner wichtigsten Eigenschaften besteht darin, dass es den Systemspeicher effektiv nutzen kann, um die Effizienz zu verbessern.

Die Verwendung von Thread-Pools ist sehr einfach. Ordnen Sie einfach die auszuführenden Aufgaben den entsprechenden Thread-Pools zu. Wenn die auszuführende Aufgabe dem entsprechenden Thread-Pool zugewiesen ist, kann sie ausgeführt werden. Die Verwendung eines Thread-Pools bringt uns viele Vorteile:

  1. Aufgaben können schneller erledigt werden. Wenn dem Thread-Pool eine Aufgabe zugewiesen wird, wird sie in einer Schleife ausgeführt, bis die Ausführung abgeschlossen ist oder der Thread neu erstellt wird.
  2. Verbesserte Effizienz der Ressourcennutzung. Wenn eine Aufgabe viele Ressourcen wie CPU, Speicher usw. erfordert, können wir den Thread-Pool verwenden, um diese Ressourcen zu verwalten, sodass jeder Thread über genügend CPU und Speicher verfügt, um die Aufgabe auszuführen.

7. Mechanismus zur Kernel-Statussynchronisierung

Zwei Synchronisationsmechanismen werden oben vorgestellt. Schauen wir uns also den Synchronisationsmechanismus im Kernel-Status an. Es gibt vier Synchronisierungsmethoden im Kernel-Status:

  1. Semaphor: Wird zum Betreiben von Sperren verwendet. Wenn ein Thread eine Sperre belegt, sendet er ein Semaphor an das System.
  2. Semaphorübertragung: Dieser Mechanismus wird vom Betriebssystem bereitgestellt. Nach dem Aufruf der Funktion sys_thread wird der Semaphor an das System übergeben.
  3. Mutex-Sperre: Diese Methode steuert hauptsächlich den Zugriff auf Ressourcen durch Priorität.
  4. Mutexe und Semaphore werden beide verwendet, um Synchronisationsprobleme zwischen Prozessen zu lösen.
  5. Eine andere Möglichkeit zur Synchronisierung ist der Thread-Pool. In diesem Prozess erstellt der Thread-Pool einen Thread, um über diesen Thread mit anderen Threads zu interagieren und einen Synchronisationseffekt zu erzielen.

8. Zusammenfassung

Durch die obige Analyse verstehen wir, dass die Synchronisierung ein komplexes Problem ist. Wie wird die Synchronisierung im Kernel-Status abgeschlossen?

Zuallererst gibt es im Kernel-Status drei Prozesse: Diese drei Prozesse können gegenseitig auf die Ressourcen zugreifen und sich auch synchronisieren, wenn Ressourcen von anderen Prozessen angefordert werden.

Wenn ein Prozess blockiert ist, entfernen alle seine untergeordneten Prozesse einen untergeordneten Prozess (oder einen anderen untergeordneten Prozess) aus der Warteschlange und fügen ihn der blockierenden Warteschlange hinzu. Wenn alle untergeordneten Prozesse blockiert sind, befinden sich keine untergeordneten Prozesse in der Blockierungswarteschlange. Zu diesem Zeitpunkt fügen andere untergeordnete Prozesse in der Warteschlange den aktuellen Thread zur Warteschlange hinzu. Diese drei Prozesse beeinflussen sich während des Wartevorgangs nicht gegenseitig. Die drei Threads können sich mit anderen Threads synchronisieren, indem sie ihre eigenen Prioritäten festlegen.

Das obige ist der detaillierte Inhalt vonAls Embedded-Entwicklungsingenieur müssen Sie den Synchronisierungsmechanismus des Linux-Kernels kennen.. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Quelle:lxlinux.net
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage