Heim > Backend-Entwicklung > Golang > Detaillierte Erläuterung des Synchronisations- und gegenseitigen Ausschlussmechanismus von Goroutinen in der gleichzeitigen Golang-Programmierung

Detaillierte Erläuterung des Synchronisations- und gegenseitigen Ausschlussmechanismus von Goroutinen in der gleichzeitigen Golang-Programmierung

PHPz
Freigeben: 2023-07-20 11:25:10
Original
1001 Leute haben es durchsucht

Detaillierte Erläuterung des Synchronisations- und gegenseitigen Ausschlussmechanismus von Goroutinen in der gleichzeitigen Golang-Programmierung

Mit der Beliebtheit von Mehrkernprozessoren und der kontinuierlichen Verbesserung der Computerleistung ist es wichtig geworden, mehrere Prozessorkerne für paralleles Rechnen voll auszunutzen Problem, mit dem Entwickler konfrontiert sind. Die gleichzeitige Programmierung ist eine der Schlüsseltechnologien zur Lösung dieses Problems. In Golang werden Goroutinen und Kanäle häufig zur Implementierung gleichzeitiger Programmierung verwendet. Unter ihnen sind Goroutinen leichtgewichtige Threads, die eine Aufgabenverarbeitung mit hoher Parallelität erreichen können. Um die korrekte Zusammenarbeit mehrerer Goroutinen sicherzustellen, spielen Synchronisations- und gegenseitige Ausschlussmechanismen eine entscheidende Rolle.

1. Das Grundkonzept von Goroutinen
In Golang sind Goroutinen leichte Threads, die gleichzeitig mit anderen Goroutinen ausgeführt werden können. Das Erstellen und Zerstören von Goroutinen kostet weniger Ressourcen als herkömmliche Threads und kann Systemressourcen effizienter nutzen.

Goroutinen werden mit dem Schlüsselwort „go“ erstellt. Der Beispielcode lautet wie folgt:

package main

import (
    "fmt"
    "time"
)

func task1() {
    for i := 0; i < 5; i++ {
        fmt.Println("Task 1:", i)
        time.Sleep(time.Millisecond * 500)
    }
}

func task2() {
    for i := 0; i < 5; i++ {
        fmt.Println("Task 2:", i)
        time.Sleep(time.Millisecond * 500)
    }
}

func main() {
    go task1()
    go task2()

    time.Sleep(time.Millisecond * 3000)
}
Nach dem Login kopieren

Im obigen Code werden zwei Goroutinen über das Schlüsselwort „go“ erstellt und führen die Funktionen task1() und task2() aus jeweils. Warten Sie in der Funktion main() 3 Sekunden bis zur Funktion time.Sleep(), um sicherzustellen, dass Goroutinen genügend Zeit haben, um die Ausführung abzuschließen. task1()task2()函数。在main()函数中,通过time.Sleep()函数等待3秒钟,保证Goroutines有足够的时间执行完毕。

二、Goroutines的同步与互斥机制
在实际的并发编程中,多个Goroutines可能需要共享某些资源。这时候就需要通过同步与互斥机制来确保资源的正确访问。

  1. 同步
    在Golang中,常用的同步机制有WaitGroup、Mutex和RWMutex。

1.1 WaitGroup
WaitGroup用于等待一组Goroutines的执行完成。它的功能类似于Java中的CountDownLatch。示例代码如下:

package main

import (
    "fmt"
    "sync"
    "time"
)

func task(i int, wg *sync.WaitGroup) {
    defer wg.Done()

    fmt.Println("Task", i)
    time.Sleep(time.Millisecond * 500)
}

func main() {
    var wg sync.WaitGroup

    for i := 0; i < 5; i++ {
        wg.Add(1)
        go task(i, &wg)
    }

    wg.Wait()
    fmt.Println("All tasks finished")
}
Nach dem Login kopieren

在上述代码中,通过sync.WaitGroup创建了一个等待组wg。在每个Goroutine的执行前调用wg.Add(1)将等待组计数器加1,表示有一个任务需要等待。在每个Goroutine执行完毕后调用wg.Done()将等待组计数器减1,表示一个任务已完成。最后,通过wg.Wait()等待所有任务执行完成。

1.2 Mutex
Mutex是一种互斥锁,用于保护共享资源在同一时间只能被一个Goroutine访问。示例代码如下:

package main

import (
    "fmt"
    "sync"
    "time"
)

var count int
var mutex sync.Mutex

func task(i int, wg *sync.WaitGroup) {
    defer wg.Done()

    mutex.Lock()
    defer mutex.Unlock()

    count++
    fmt.Println("Task", i, "count:", count)
    time.Sleep(time.Millisecond * 500)

    mutex.Lock()
    defer mutex.Unlock()

    count--
}

func main() {
    var wg sync.WaitGroup

    for i := 0; i < 5; i++ {
        wg.Add(1)
        go task(i, &wg)
    }

    wg.Wait()
    fmt.Println("All tasks finished")
}
Nach dem Login kopieren

在上述代码中,通过sync.Mutex创建了一个互斥锁mutex。在每个Goroutine中,通过调用mutex.Lock()mutex.Unlock()的配对来保护共享资源的访问。在实际的应用中,可以将需要保护的共享资源存放在结构体中,通过结构体中的互斥锁来控制对共享资源的访问。

  1. 互斥
    除了同步外,有时候还需要通过互斥来保证某段代码在同一时间只能被一个Goroutine执行。在Golang中,常用的互斥机制有Once和Mutex。

2.1 Once
Once用于保证某段代码在程序运行期间只会执行一次。示例代码如下:

package main

import (
    "fmt"
    "sync"
)

var once sync.Once

func task() {
    fmt.Println("Task executed")
}

func main() {
    for i := 0; i < 5; i++ {
        once.Do(task)
    }
}
Nach dem Login kopieren

在上述代码中,通过sync.Once创建了一个Once对象once。在每个Goroutine中,通过调用once.Do(task)来保证task()函数在整个程序运行期间只会执行一次。

2.2 Mutex
Mutex也可以用来实现互斥。示例代码如下:

package main

import (
    "fmt"
    "sync"
    "time"
)

var count int
var mutex sync.Mutex

func task(i int, wg *sync.WaitGroup) {
    defer wg.Done()

    mutex.Lock()
    defer mutex.Unlock()

    fmt.Println("Task", i)
    time.Sleep(time.Millisecond * 500)
}

func main() {
    var wg sync.WaitGroup

    for i := 0; i < 5; i++ {
        wg.Add(1)
        go task(i, &wg)
    }

    wg.Wait()
    fmt.Println("All tasks finished")
}
Nach dem Login kopieren

在上述代码中,通过调用mutex.Lock()mutex.Unlock()来保证在同一时间只能有一个Goroutine执行task()

2. Synchronisierungs- und gegenseitiger Ausschlussmechanismus von Goroutinen

Bei der tatsächlichen gleichzeitigen Programmierung müssen möglicherweise mehrere Goroutinen bestimmte Ressourcen gemeinsam nutzen. Zu diesem Zeitpunkt sind Synchronisierungs- und gegenseitige Ausschlussmechanismen erforderlich, um den korrekten Zugriff auf Ressourcen sicherzustellen.

  1. SynchronisationIn Golang gehören zu den häufig verwendeten Synchronisationsmechanismen WaitGroup, Mutex und RWMutex.
🎜1.1 WaitGroup🎜WaitGroup wird verwendet, um auf den Abschluss der Ausführung einer Gruppe von Goroutinen zu warten. Seine Funktionalität ähnelt CountDownLatch in Java. Der Beispielcode lautet wie folgt: 🎜rrreee🎜Im obigen Code wird eine Wartegruppe wg über sync.WaitGroup erstellt. Rufen Sie wg.Add(1) auf, bevor jede Goroutine ausgeführt wird, um den Wartegruppenzähler um 1 zu erhöhen und anzuzeigen, dass es eine Aufgabe gibt, die warten muss. Nachdem jede Goroutine ausgeführt wurde, rufen Sie wg.Done() auf, um den Wartegruppenzähler um 1 zu verringern und anzuzeigen, dass eine Aufgabe abgeschlossen wurde. Warten Sie abschließend, bis alle Aufgaben mit wg.Wait() abgeschlossen sind. 🎜🎜1.2 Mutex🎜Mutex ist eine Mutex-Sperre, die zum Schutz gemeinsam genutzter Ressourcen verwendet wird, auf die nur eine Goroutine gleichzeitig zugreifen kann. Der Beispielcode lautet wie folgt: 🎜rrreee🎜Im obigen Code wird eine Mutex-Sperre mutex durch sync.Mutex erstellt. In jeder Goroutine wird der Zugriff auf gemeinsam genutzte Ressourcen durch den Aufruf eines Paares aus mutex.Lock() und mutex.Unlock() geschützt. In tatsächlichen Anwendungen können die zu schützenden gemeinsam genutzten Ressourcen in der Struktur gespeichert werden und der Zugriff auf die gemeinsam genutzten Ressourcen kann über die Mutex-Sperre in der Struktur gesteuert werden. 🎜
  1. Gegenseitiger Ausschluss🎜Neben der Synchronisierung ist manchmal auch ein gegenseitiger Ausschluss erforderlich, um sicherzustellen, dass ein bestimmter Codeabschnitt nur von einer Goroutine gleichzeitig ausgeführt werden kann. Zu den in Golang häufig verwendeten gegenseitigen Ausschlussmechanismen gehören Once und Mutex.
🎜2.1 Once🎜Once wird verwendet, um sicherzustellen, dass ein bestimmter Codeabschnitt während der Ausführung des Programms nur einmal ausgeführt wird. Der Beispielcode lautet wie folgt: 🎜rrreee🎜Im obigen Code wird ein Once-Objekt once durch sync.Once erstellt. In jeder Goroutine sorgt der Aufruf von once.Do(task) dafür, dass die Funktion task() während der gesamten Programmlaufzeit nur einmal ausgeführt wird. 🎜🎜2.2 Mutex🎜Mutex kann auch zur Umsetzung des gegenseitigen Ausschlusses verwendet werden. Der Beispielcode lautet wie folgt: 🎜rrreee🎜Im obigen Code wird durch Aufrufen von mutex.Lock() und mutex.Unlock() sichergestellt, dass nur eine Goroutine vorhanden sein kann Gleichzeitig wird die task()-Funktion ausgeführt und auf gemeinsam genutzte Ressourcen zugegriffen. 🎜🎜Zusammenfassung🎜Durch die Einleitung dieses Artikels haben wir etwas über den Synchronisations- und gegenseitigen Ausschlussmechanismus von Goroutinen in der gleichzeitigen Golang-Programmierung erfahren. In tatsächlichen Anwendungen sind Synchronisations- und gegenseitige Ausschlussmechanismen der Schlüssel zur Gewährleistung einer korrekten Zusammenarbeit zwischen mehreren Goroutinen. Durch die ordnungsgemäße Verwendung von Synchronisations- und gegenseitigen Ausschlussmechanismen wie WaitGroup, Mutex und RWMutex kann der korrekte Zugriff auf gemeinsam genutzte Ressourcen sichergestellt und so eine effiziente gleichzeitige Programmierung erreicht werden. 🎜

Das obige ist der detaillierte Inhalt vonDetaillierte Erläuterung des Synchronisations- und gegenseitigen Ausschlussmechanismus von Goroutinen in der gleichzeitigen Golang-Programmierung. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
Quelle:php.cn
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