Heim  >  Artikel  >  Backend-Entwicklung  >  Golang implementiert gleichzeitige Programmierung

Golang implementiert gleichzeitige Programmierung

王林
王林Original
2023-05-12 22:01:37900Durchsuche

Go-Sprache (Golang) ist eine leichte gleichzeitige Programmiersprache, die Entwicklern den Umgang mit gleichzeitiger Programmierung erleichtern soll. Golang bietet eine Fülle von Sprachfunktionen und Bibliotheksfunktionen, mit denen sich Programmieraufgaben mit hoher Parallelität problemlos implementieren lassen. In diesem Artikel werden Golangs Methoden und Techniken zur Implementierung der gleichzeitigen Programmierung vorgestellt.

1. Goroutinen und Kanäle
Goroutinen und Kanäle sind zwei Kernkonzepte der gleichzeitigen Programmierung in Golang. Sie sind der Schlüssel zur Entwicklung effizienter gleichzeitiger Programme mit Golang. Goroutinen sind leichtgewichtige Threads in Golang. Jede Funktion in Golang kann als Goroutine ausgeführt werden. Kanäle sind Kanäle für die Kommunikation zwischen Goroutinen, über die Daten zwischen mehreren Goroutinen übertragen werden können.

Das folgende Beispiel zeigt, wie man ein einfaches gleichzeitiges Programm mithilfe von Goroutinen und Kanälen implementiert:

package main

import (
    "fmt"
    "time"
)

func worker(id int, jobs <-chan int, results chan<- int) {
    for j := range jobs {
        fmt.Println("worker", id, "started job", j)
        time.Sleep(time.Second)
        fmt.Println("worker", id, "finished job", j)
        results <- j * 2
    }
}

func main() {
    jobs := make(chan int, 100)
    results := make(chan int, 100)

    for w := 1; w <= 3; w++ {
        go worker(w, jobs, results)
    }

    for j := 1; j <= 9; j++ {
        jobs <- j
    }
    close(jobs)

    for a := 1; a <= 9; a++ {
        <-results
    }
}

Im obigen Beispiel wird die Worker-Funktion als Goroutine ausgeführt, ruft die Aufgaben aus der Jobs-Pipeline ab und sendet die Ergebnisse nach der Verarbeitung an results Pipeline. Die Hauptfunktion erstellt zwei Pipelines, Jobs und Ergebnisse, sendet Aufgaben an die Job-Pipeline und wartet schließlich darauf, dass alle Ergebnisse aus der Ergebnis-Pipeline entnommen werden.

2. WaitGroups
WaitGroups ist eine weitere wichtige Ressource in der Golang-Bibliothek. Es handelt sich um einen Mechanismus zum Warten auf den Abschluss einer Gruppe von Goroutinen. Wenn Sie darauf warten müssen, dass eine Gruppe von Goroutinen eine bestimmte Aufgabe erledigt, können Sie WaitGroup verwenden, das drei Methoden bereitstellt: Hinzufügen, Fertig und Warten. Die Add-Methode im Code gibt die Anzahl der Goroutinen an, die warten müssen, die Done-Methode gibt an, dass eine bestimmte Goroutine die Aufgabe abgeschlossen hat, und die Wait-Methode blockiert und wartet darauf, dass alle Goroutinen die Aufgabe abschließen.

Das folgende Beispiel zeigt, wie WaitGroup zum Implementieren einer einfachen gleichzeitigen Aufgabe verwendet wird:

package main

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

func worker(id int, wg *sync.WaitGroup) {
    defer wg.Done()

    fmt.Printf("Worker %d starting
", id)

    time.Sleep(time.Second)
    fmt.Printf("Worker %d done
", id)
}

func main() {
    var wg sync.WaitGroup

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

    wg.Wait()

    fmt.Println("All workers done")
}

Im obigen Beispiel wird die Worker-Funktion als Goroutine ausgeführt und wartet darauf, dass alle Goroutinen über WaitGroup abgeschlossen werden. Erstellen Sie in der Hauptfunktion eine WaitGroup und treten Sie mit der Add-Methode in die Warteliste ein. Die Done-Methode zeigt an, dass eine bestimmte Goroutine die Aufgabe abgeschlossen hat, und wartet darauf, dass alle Goroutinen die Aufgabe abschließen.

3. Mutexes
Mutexes ist ein weiteres sehr wichtiges Tool zur gleichzeitigen Programmierung, das in der Golang-Bibliothek bereitgestellt wird. Es kann die Datensicherheit gewährleisten, wenn Ressourcen von mehreren Goroutinen gemeinsam genutzt werden. Es kann Ressourcen sperren und entsperren, um sicherzustellen, dass nur eine Goroutine gleichzeitig auf gemeinsam genutzte Ressourcen zugreifen kann.

Das folgende Beispiel zeigt, wie Mutexe verwendet werden, um eine gleichzeitige Aufgabe zu implementieren:

package main

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

type SafeCounter struct {
    value int
    mutex sync.Mutex
}

func (c *SafeCounter) Increment() {
    c.mutex.Lock()

    c.value++
    fmt.Println(c.value)

    c.mutex.Unlock()
}

func main() {
    counter := SafeCounter{0, sync.Mutex{}}

    for i := 0; i < 10; i++ {
        go func() {
            for {
                counter.Increment()
                time.Sleep(time.Millisecond)
            }
        }()
    }
    time.Sleep(time.Second)
}

Im obigen Beispiel enthält der SafeCounter-Typ einen Variablenwert und einen Mutex-Mutex. Die Increment-Methode fügt der Wertvariablen 1 hinzu. Da es sich bei value um eine gemeinsam genutzte Ressource handelt, muss der Mutex in der Methode gesperrt und entsperrt werden, um sicherzustellen, dass nur eine Goroutine gleichzeitig auf die Wertvariable zugreifen kann.

4. Atomic
Atomic ist ein weiteres gleichzeitiges Programmiertool, das in der Golang-Bibliothek bereitgestellt wird. Es kann die Atomizität von Daten sicherstellen, wenn Ressourcen von mehreren Goroutinen gemeinsam genutzt werden. Atomic bietet eine Vielzahl atomarer Operationen basierend auf CPU-Anweisungen, z. B. Hinzufügen, Vergleichen und Austauschen, Laden, Speichern und andere Methoden.

Das folgende Beispiel zeigt, wie man Atomic verwendet, um eine einfache gleichzeitige Aufgabe zu implementieren:

package main

import (
    "fmt"
    "sync/atomic"
    "time"
)

func main() {
    var counter int32

    for i := 0; i < 10; i++ {
        go func() {
            for {
                atomic.AddInt32(&counter, 1)
                fmt.Println(atomic.LoadInt32(&counter))
                time.Sleep(time.Millisecond)
            }
        }()
    }
    time.Sleep(time.Second)
}

Im obigen Beispiel wird ein Zähler mithilfe der Methoden AddInt32 und LoadInt32 von Atomic implementiert. Die AddInt32-Methode erhöht den Wert des Zählers und die LoadInt32-Methode ruft den aktuellen Wert des Zählers ab. Da diese atomaren Operationen die Atomizität der Operation sicherstellen können, kann die Korrektheit der Zählererhöhung garantiert werden.

5. Select
Select ist ein weiteres sehr wichtiges Tool für die gleichzeitige Programmierung in Golang. Es handelt sich um einen Mechanismus zum gleichzeitigen Warten auf Nachrichten auf mehreren Kanälen, der Entwicklern bei der Bewältigung komplexer gleichzeitiger Aufgaben helfen kann. In der Select-Anweisung können Sie mehrere Kanäle deklarieren, dann darauf warten, dass einer der Kanäle Daten überträgt, und dann die entsprechende Logik ausführen.

Das folgende Beispiel zeigt, wie Sie mit der Select-Anweisung eine einfache gleichzeitige Aufgabe implementieren:

package main

import (
    "fmt"
    "time"
)

func main() {
    channel1 := make(chan string)
    channel2 := make(chan string)

    go func() {
        time.Sleep(time.Second)
        channel1 <- "Hello"
    }()
    go func() {
        time.Sleep(time.Second * 2)
        channel2 <- "World"
    }()

    for i := 0; i < 2; i++ {
        select {
        case message1 := <-channel1:
            fmt.Println("Received message1", message1)
        case message2 := <-channel2:
            fmt.Println("Received message2", message2)
        }
    }
}

Im obigen Beispiel werden zwei Kanäle in der Hauptfunktion deklariert: Kanal1 und Kanal2. Verwenden Sie zwei Goroutinen, um Nachrichten an diese beiden Kanäle zu senden. Verwenden Sie dann Select in der Hauptfunktion, um auf die Übertragung der Nachricht zu warten, und drucken Sie die entsprechenden Informationen entsprechend der jeweiligen Situation aus.

Fazit
Golang bietet viele leistungsstarke Tools und Bibliotheken für die gleichzeitige Programmierung, darunter Goroutinen, Kanäle, WaitGroups, Mutexes, Atomic, Select usw. Diese Tools erleichtern die Implementierung effizienter gleichzeitiger Programmieraufgaben. Beim Schreiben gleichzeitiger Programme müssen Sie auf die Sicherheit und Korrektheit der Daten achten, um Probleme wie Deadlocks und Race Conditions zu vermeiden.

Das obige ist der detaillierte Inhalt vonGolang implementiert gleichzeitige Programmierung. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
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