Über Mutex in der gleichzeitigen Go-Programmierung
vorzustellen. Ich hoffe, dass es den Freunden, die es brauchen, hilfreich sein wird! Freundliche Erinnerung: Das Lesen dieses Artikels dauert etwa 5 Minuten und 45 Sekunden. Bitte geben Sie mir weitere Hinweise zu etwaigen Mängeln. Beim Entwurf unserer häufigeren Großprojekte treten häufig Parallelitätsprobleme auf, um die Genauigkeit der Daten zu verbessern und sicherzustellen, dass die Daten im selben kritischen Abschnitt nur von einem Thread bearbeitet werden können Szenarien, die im täglichen Leben verwendet werden. Von:
Zähler
: Das Zählerergebnis ist ungenau;- Sekunden-Kill-System
- : Überverkauft aufgrund einer großen Anzahl von Besuchen gleichzeitig; Überziehung durch gleichzeitige Zahlung; Pufferdatenausnahme
- : Datenverwirrung durch Aktualisierung des Puffers. Bei allen oben genannten Problemen handelt es sich um Probleme der Datengenauigkeit, die durch Parallelität verursacht werden. Die entscheidende Lösung ist die Verwendung von
- Mutex-Sperre, dem Mutex-Parallelitätsprimitiv, das in der heutigen gleichzeitigen Programmierung beschrieben wird.
- Implementierungsmechanismus Mutex-Sperre Mutex ist ein Parallelitätskontrollmechanismus, der eingerichtet wurde, um Parallelitätskonkurrenz zu vermeiden. Es enthält das Konzept eines „kritischen Abschnitts“.
Wenn im Prozess der gleichzeitigen Programmierung gleichzeitig auf einige Ressourcen oder Variablen im Programm zugegriffen oder diese geändert werden, muss dieser Teil des Programms zuerst geschützt und dann betrieben werden, um Datenungenauigkeiten durch gleichzeitigen Zugriff zu vermeiden. und der Schutz nach Abschluss des Vorgangs entfernt wird, wird dieser Teil des geschützten Programms als „kritischer Abschnitt“ bezeichnet.
Verwenden Sie eine Mutex-Sperre, um den kritischen Abschnitt so zu begrenzen, dass er gleichzeitig nur von einem Thread gehalten wird. Wenn der kritische Abschnitt zu diesem Zeitpunkt von einem Thread gehalten wird, schlagen andere Threads fehl oder warten, bis sie eintreten möchten Wenn Sie die Sperre aufheben, wird der Thread, der diesen kritischen Abschnitt enthält, beendet und andere Threads haben die Möglichkeit, diesen kritischen Abschnitt abzurufen.
Diagramm des kritischen Abschnitts von Go-Mutex Mutex ist das am weitesten verbreitete Synchronisationsprimitiv in der Go-Sprache, auch Parallelitätsprimitiv genannt.
Es löst das Problem des gleichzeitigen Lesens und Schreibens gemeinsam genutzter Ressourcen, um Datenwettlaufprobleme zu vermeiden .
Grundlegende Verwendung
Mutex bietet zwei Methoden: Sperren und Entsperren: Verwenden Sie beim Betreten des kritischen Abschnitts die Lock-Methode zum Sperren und beim Verlassen des kritischen Abschnitts die Unlock-Methode, um die Sperre aufzuheben.
type Locker interface { Lock() Unlock()}func(m *Mutex)Lock()func(m *Mutex)Unlock()
Wenn eine Goroutine die Lock-Methode aufruft, um die Sperre zu erhalten, blockieren andere Goroutinen den Lock-Aufruf, bis die Goroutine, die gerade die Sperre erwirbt, die Sperre aufhebt.
Das Folgende ist ein Beispiel für einen Zähler, der von 100 Goroutinen ausgeführt wird, um den Zähler zu akkumulieren, und das endgültige Ausgabeergebnis ist:
package mainimport (
"fmt"
"sync")func main() {
var mu sync.Mutex
countNum := 0
// 确认辅助变量是否都执行完成
var wg sync.WaitGroup // wg 添加数目要和 创建的协程数量保持一致
wg.Add(100)
for i := 0; i < 100; i++ {
go func() {
defer wg.Done()
for j := 0; j < 1000; j++ {
mu.Lock()
countNum++
mu.Unlock()
}
}()
}
wg.Wait()
fmt.Printf("countNum: %d", countNum)}
Nach dem Login kopieren
Tatsächliche Verwendungpackage mainimport ( "fmt" "sync")func main() { var mu sync.Mutex countNum := 0 // 确认辅助变量是否都执行完成 var wg sync.WaitGroup // wg 添加数目要和 创建的协程数量保持一致 wg.Add(100) for i := 0; i < 100; i++ { go func() { defer wg.Done() for j := 0; j < 1000; j++ { mu.Lock() countNum++ mu.Unlock() } }() } wg.Wait() fmt.Printf("countNum: %d", countNum)}
Oft wird Mutex nicht allein verwendet, sondern verschachtelt in einer Struktur Wird als Teil der Struktur verwendet. Wenn die eingebettete Struktur mehrere Felder hat, platzieren wir normalerweise den Mutex auf dem zu steuernden Feld und verwenden dann Leerzeichen, um die Felder zu trennen.
Sie können sogar die Logik des Erwerbs von Sperren, der Freigabe von Sperren und des Zählens um eins in einer Methode kapseln.
package mainimport ( "fmt" "sync")// 线程安全的计数器type Counter struct { CounterType int Name string mu sync.Mutex count uint64}// 加一方法func (c *Counter) Incr() { c.mu.Lock() defer c.mu.Unlock() c.count++}// 取数值方法 线程也需要受保护func (c *Counter) Count() uint64 { c.mu.Lock() defer c.mu.Unlock() return c.count}func main() { // 定义一个计数器 var counter Counter var wg sync.WaitGroup wg.Add(100) for i := 0; i < 100; i++ { go func() { defer wg.Done() for j := 0; j < 1000; j++ { counter.Incr() } }() } wg.Wait() fmt.Printf("%d\n", counter.Count())}
Denkfragen
F: Sie wissen bereits, dass andere wartende Goroutinen nur ewig warten können, wenn ein Mutex von einer Goroutine gesperrt wurde. Welche der wartenden Goroutinen erhält den Mutex also zuerst, nachdem die Sperre aufgehoben wurde?A: FIFO-Strategie: Bei der Goroutine-Planung wird eine Warteschlange verwaltet, um die Ausführung der Goroutine sicherzustellen. Wenn die Goroutine, die die Sperre erhält, den Vorgang des kritischen Abschnitts abschließt, wird die Sperre freigegeben. In der Warteschlange Die in der Warteschlange an erster Stelle stehende Goroutine erhält die Sperre und führt kritische Abschnittsoperationen aus.
Das obige ist der detaillierte Inhalt vonÜber Mutex in der gleichzeitigen Go-Programmierung. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Heiße KI -Werkzeuge

Undresser.AI Undress
KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover
Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool
Ausziehbilder kostenlos

Clothoff.io
KI-Kleiderentferner

AI Hentai Generator
Erstellen Sie kostenlos Ai Hentai.

Heißer Artikel

Heiße Werkzeuge

Notepad++7.3.1
Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version
Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1
Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6
Visuelle Webentwicklungstools

SublimeText3 Mac-Version
Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Heiße Themen



In Go umfasst der Funktionslebenszyklus Definition, Laden, Verknüpfen, Initialisieren, Aufrufen und Zurückgeben; der Variablenbereich ist in Funktionsebene und Blockebene unterteilt. Variablen innerhalb einer Funktion sind intern sichtbar, während Variablen innerhalb eines Blocks nur innerhalb des Blocks sichtbar sind .

In Go können Sie reguläre Ausdrücke verwenden, um Zeitstempel abzugleichen: Kompilieren Sie eine Zeichenfolge mit regulären Ausdrücken, z. B. die, die zum Abgleich von ISO8601-Zeitstempeln verwendet wird: ^\d{4}-\d{2}-\d{2}T \d{ 2}:\d{2}:\d{2}(\.\d+)?(Z|[+-][0-9]{2}:[0-9]{2})$ . Verwenden Sie die Funktion regexp.MatchString, um zu überprüfen, ob eine Zeichenfolge mit einem regulären Ausdruck übereinstimmt.

In Go können WebSocket-Nachrichten mit dem Paket gorilla/websocket gesendet werden. Konkrete Schritte: Stellen Sie eine WebSocket-Verbindung her. Senden Sie eine Textnachricht: Rufen Sie WriteMessage(websocket.TextMessage,[]byte("message")) auf. Senden Sie eine binäre Nachricht: Rufen Sie WriteMessage(websocket.BinaryMessage,[]byte{1,2,3}) auf.

Go und die Go-Sprache sind unterschiedliche Einheiten mit unterschiedlichen Eigenschaften. Go (auch bekannt als Golang) ist bekannt für seine Parallelität, schnelle Kompilierungsgeschwindigkeit, Speicherverwaltung und plattformübergreifende Vorteile. Zu den Nachteilen der Go-Sprache gehören ein weniger umfangreiches Ökosystem als andere Sprachen, eine strengere Syntax und das Fehlen dynamischer Typisierung.

Speicherlecks können dazu führen, dass der Speicher des Go-Programms kontinuierlich zunimmt, indem: Ressourcen geschlossen werden, die nicht mehr verwendet werden, wie z. B. Dateien, Netzwerkverbindungen und Datenbankverbindungen. Verwenden Sie schwache Referenzen, um Speicherlecks zu verhindern, und zielen Sie auf Objekte für die Garbage Collection ab, wenn sie nicht mehr stark referenziert sind. Bei Verwendung von Go-Coroutine wird der Speicher des Coroutine-Stapels beim Beenden automatisch freigegeben, um Speicherverluste zu vermeiden.

In Golang können Sie mit Fehler-Wrappern neue Fehler erstellen, indem Sie Kontextinformationen an den ursprünglichen Fehler anhängen. Dies kann verwendet werden, um die von verschiedenen Bibliotheken oder Komponenten ausgelösten Fehlertypen zu vereinheitlichen und so das Debuggen und die Fehlerbehandlung zu vereinfachen. Die Schritte lauten wie folgt: Verwenden Sie die Funktion „errors.Wrap“, um die ursprünglichen Fehler in neue Fehler umzuwandeln. Der neue Fehler enthält Kontextinformationen zum ursprünglichen Fehler. Verwenden Sie fmt.Printf, um umschlossene Fehler auszugeben und so mehr Kontext und Umsetzbarkeit bereitzustellen. Wenn Sie verschiedene Fehlertypen behandeln, verwenden Sie die Funktion „errors.Wrap“, um die Fehlertypen zu vereinheitlichen.

Das Testen gleichzeitiger Funktionen in Einheiten ist von entscheidender Bedeutung, da dies dazu beiträgt, ihr korrektes Verhalten in einer gleichzeitigen Umgebung sicherzustellen. Beim Testen gleichzeitiger Funktionen müssen grundlegende Prinzipien wie gegenseitiger Ausschluss, Synchronisation und Isolation berücksichtigt werden. Gleichzeitige Funktionen können Unit-Tests unterzogen werden, indem Rennbedingungen simuliert, getestet und Ergebnisse überprüft werden.

Es gibt zwei Schritte zum Erstellen einer Prioritäts-Goroutine in der Go-Sprache: Registrieren einer benutzerdefinierten Goroutine-Erstellungsfunktion (Schritt 1) und Angeben eines Prioritätswerts (Schritt 2). Auf diese Weise können Sie Goroutinen mit unterschiedlichen Prioritäten erstellen, die Ressourcenzuteilung optimieren und die Ausführungseffizienz verbessern.
