Maison >développement back-end >Golang >Utilisation avancée des Goroutines et des canaux dans Golang

Utilisation avancée des Goroutines et des canaux dans Golang

PHPz
PHPzoriginal
2023-08-07 12:12:211216parcourir

Utilisation avancée des Goroutines et des canaux dans Golang

Dans la programmation simultanée de Golang, les Goroutines et les canaux sont deux concepts très importants. Les Goroutines sont des threads légers qui peuvent s'exécuter simultanément, tandis que les canaux sont le mécanisme de communication entre les Goroutines. Dans cet article, nous explorerons l'utilisation avancée des Goroutines et des canaux dans Golang et l'illustrons avec des exemples de code.

1. Utilisation avancée des Goroutines

  1. Le multiplexage des Goroutines peut être réalisé via l'instruction select. Dans l'exemple de code ci-dessous, nous créons deux Goroutines pour calculer respectivement la séquence de Fibonacci et la factorielle. Grâce à l'instruction select, nous pouvons attendre que deux Goroutines se terminent en même temps et imprimer les résultats du calcul.
package main

import (
    "fmt"
)

func fibonacci(n int, c chan<- int) {
    x, y := 0, 1
    for i := 0; i < n; i++ {
        c <- x
        x, y = y, x+y
    }
    close(c)
}

func factorial(n int, c chan<- int) {
    result := 1
    for i := 1; i <= n; i++ {
        result *= i
    }
    c <- result
    close(c)
}

func main() {
    fibChan := make(chan int)
    factChan := make(chan int)

    go fibonacci(10, fibChan)
    go factorial(5, factChan)

    for {
        select {
        case fib, ok := <-fibChan:
            if ok {
                fmt.Println("Fibonacci:", fib)
            } else {
                fibChan = nil
            }

        case fact, ok := <-factChan:
            if ok {
                fmt.Println("Factorial:", fact)
            } else {
                factChan = nil
            }

        default:
            if fibChan == nil && factChan == nil {
                return
            }
        }
    }
}
  1. Vous pouvez attendre la fin des Goroutines via WaitGroup. WaitGroup est un compteur qui peut être utilisé pour attendre la fin d'un groupe de Goroutines. Dans l'exemple de code ci-dessous, nous créons deux Goroutines pour calculer respectivement la séquence de Fibonacci et la factorielle. Avec sync.WaitGroup, nous pouvons attendre que deux Goroutines se terminent simultanément.
package main

import (
    "fmt"
    "sync"
)

func fibonacci(n int, c chan<- int, wg *sync.WaitGroup) {
    defer wg.Done()
    x, y := 0, 1
    for i := 0; i < n; i++ {
        c <- x
        x, y = y, x+y
    }
    close(c)
}

func factorial(n int, c chan<- int, wg *sync.WaitGroup) {
    defer wg.Done()
    result := 1
    for i := 1; i <= n; i++ {
        result *= i
    }
    c <- result
    close(c)
}

func main() {
    fibChan := make(chan int)
    factChan := make(chan int)
    var wg sync.WaitGroup

    wg.Add(2)

    go fibonacci(10, fibChan, &wg)
    go factorial(5, factChan, &wg)

    go func() {
        wg.Wait()
        close(fibChan)
        close(factChan)
    }()

    for {
        select {
        case fib, ok := <-fibChan:
            if ok {
                fmt.Println("Fibonacci:", fib)
            } else {
                fibChan = nil
            }

        case fact, ok := <-factChan:
            if ok {
                fmt.Println("Factorial:", fact)
            } else {
                factChan = nil
            }

        default:
            if fibChan == nil && factChan == nil {
                return
            }
        }
    }
}

2. Utilisation avancée des canaux

  1. Vous pouvez contrôler le comportement de blocage du canal en définissant la taille du tampon. Par défaut, le canal est sans tampon, c'est-à-dire que l'envoi et la réception seront bloqués jusqu'à ce que l'autre partie soit prête. Nous pouvons définir la taille du tampon via le deuxième paramètre de la fonction make. Dans l'exemple de code suivant, nous créons un canal avec une taille de tampon de 3 et lui envoyons 3 valeurs. Le tampon n'étant pas plein, l'envoi ne bloque pas.
package main

import (
    "fmt"
)

func main() {
    ch := make(chan int, 3)
    ch <- 1
    ch <- 2
    ch <- 3

    fmt.Println(<-ch)
    fmt.Println(<-ch)
    fmt.Println(<-ch)
}
  1. Vous pouvez parcourir Channel via le mot-clé range. Le mot-clé range peut être utilisé pour parcourir les valeurs dans le canal. Lorsque le canal est fermé, l'itération se termine automatiquement. Dans l'exemple de code suivant, nous créons un compteur Goroutines et envoyons 5 valeurs à un canal sans tampon. Dans la fonction principale, nous utilisons le mot-clé range pour parcourir les valeurs dans le canal et les imprimer. Lorsque le canal est fermé, la boucle de plage se termine automatiquement.
package main

import (
    "fmt"
    "time"
)

func counter(ch chan<- int) {
    for i := 1; i <= 5; i++ {
        ch <- i
        time.Sleep(time.Second)
    }
    close(ch)
}

func main() {
    ch := make(chan int)
    go counter(ch)

    for val := range ch {
        fmt.Println(val)
    }
}

Pour résumer, les Goroutines et les canaux de Golang offrent des capacités de programmation simultanée puissantes et flexibles. Nous avons plus de contrôle sur le comportement des Goroutines et des canaux grâce à une utilisation avancée telle que les instructions select, WaitGroup, les tampons et les mots-clés range. Nous espérons que les exemples de code donnés dans cet article pourront aider les lecteurs à mieux comprendre et appliquer ces utilisations avancées.

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