Maison  >  Article  >  développement back-end  >  Golang implémente la programmation simultanée

Golang implémente la programmation simultanée

王林
王林original
2023-05-12 22:01:37948parcourir

Le langage Go (golang) est un langage de programmation simultané léger, conçu pour faciliter la gestion de la programmation simultanée par les développeurs. Golang fournit une multitude de fonctionnalités de langage et de fonctions de bibliothèque qui peuvent facilement implémenter des tâches de programmation à haute concurrence. Cet article présentera les méthodes et techniques de Golang pour implémenter la programmation simultanée.

1. Goroutines et canaux
Les goroutines et les canaux sont deux concepts fondamentaux de la programmation simultanée dans Golang. Ils sont la clé du développement de programmes simultanés efficaces utilisant Golang. Les Goroutines sont des threads légers dans Golang. Chaque fonction de Golang peut s'exécuter comme une Goroutine. Les canaux sont des canaux utilisés pour la communication entre les Goroutines, à travers lesquels les données peuvent être transférées entre plusieurs Goroutines.

L'exemple suivant montre comment implémenter un programme simultané simple à l'aide de Goroutines et de canaux :

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
    }
}

Dans l'exemple ci-dessus, la fonction de travail s'exécute comme une goroutine, récupère les tâches du pipeline de tâches et envoie les résultats aux résultats après traitement. pipeline. La fonction principale crée deux pipelines, des tâches et des résultats, envoie des tâches au pipeline de tâches et attend enfin que tous les résultats soient retirés du pipeline de résultats.

2. WaitGroups
WaitGroups est une autre ressource clé de la bibliothèque Golang. Il s'agit d'un mécanisme permettant d'attendre la fin de l'exécution d'un groupe de Goroutines. Lorsque vous devez attendre qu'un groupe de Goroutines termine une certaine tâche, vous pouvez utiliser WaitGroup, qui propose trois méthodes : Ajouter, Terminé et Attendre. La méthode Add dans le code indique le nombre de Goroutines qui doivent attendre, la méthode Done indique qu'un certain Goroutine a terminé la tâche et la méthode Wait bloque et attend que toutes les Goroutines terminent la tâche.

L'exemple suivant montre comment utiliser WaitGroup pour implémenter une tâche simultanée simple :

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")
}

Dans l'exemple ci-dessus, la fonction de travail s'exécute comme un Goroutine, attendant que tous les Goroutines se terminent via WaitGroup. Dans la fonction principale, créez un WaitGroup et utilisez la méthode Add pour rejoindre la liste d'attente. La méthode Done indique qu'un certain Goroutine a terminé la tâche. La méthode Wait bloquera et attendra que tous les Goroutines terminent la tâche.

3. Mutexes
Mutex est un autre outil de programmation simultanée très important fourni dans la bibliothèque Golang. Il peut garantir la sécurité des données lorsque les ressources sont partagées entre plusieurs Goroutines. Il peut garantir qu'un seul Goroutine peut accéder aux ressources partagées en même temps en verrouillant et déverrouillant les ressources.

L'exemple suivant montre comment utiliser les mutex pour implémenter une tâche simultanée :

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)
}

Dans l'exemple ci-dessus, le type SafeCounter contient une valeur de variable et un mutex mutex. La méthode Increment ajoutera 1 à la variable de valeur Étant donné que la valeur est une ressource partagée, le mutex doit être verrouillé et déverrouillé dans la méthode pour garantir qu'un seul Goroutine peut accéder à la variable de valeur en même temps.

4. Atomic
Atomic est un autre outil de programmation simultanée fourni dans la bibliothèque Golang. Il peut garantir l'atomicité des données lorsque les ressources sont partagées entre plusieurs Goroutines. Atomic fournit une variété d'opérations atomiques basées sur les instructions du processeur, telles que l'ajout, la comparaison et l'échange, le chargement, le stockage et d'autres méthodes.

L'exemple suivant montre comment utiliser Atomic pour implémenter une tâche simultanée simple :

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)
}

Dans l'exemple ci-dessus, un compteur est implémenté à l'aide des méthodes AddInt32 et LoadInt32 d'Atomic. La méthode AddInt32 augmente la valeur du compteur et la méthode LoadInt32 obtient la valeur actuelle du compteur. Étant donné que ces opérations atomiques peuvent garantir l'atomicité de l'opération, l'exactitude de l'incrément du compteur peut être garantie.

5. Select
Select est un autre outil de programmation simultanée très important dans Golang. Il s'agit d'un mécanisme permettant d'attendre des messages sur plusieurs canaux en même temps, ce qui peut aider les développeurs à gérer des tâches simultanées complexes. Dans l'instruction Select, vous pouvez déclarer plusieurs canaux, puis attendre que l'un des canaux transmette des données, puis exécuter la logique correspondante.

L'exemple suivant montre comment utiliser l'instruction Select pour implémenter une tâche simultanée simple :

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)
        }
    }
}

Dans l'exemple ci-dessus, deux canaux sont déclarés dans la fonction principale : canal1 et canal2. Utilisez deux Goroutines pour envoyer des messages à ces deux canaux, puis utilisez Select dans la fonction principale pour attendre la transmission du message, et imprimez les informations correspondantes en fonction de la situation spécifique.

Conclusion
Golang fournit de nombreux outils et bibliothèques de programmation simultanée puissants, notamment Goroutines, Channels, WaitGroups, Mutexes, Atomic, Select, etc. Ces outils facilitent la mise en œuvre de tâches de programmation simultanées efficaces. Lors de l'écriture de programmes simultanés, vous devez veiller à garantir la sécurité et l'exactitude des données afin d'éviter des problèmes tels que des blocages et des conditions de concurrence.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn