Maison  >  Article  >  développement back-end  >  Modèle producteur-consommateur

Modèle producteur-consommateur

王林
王林original
2024-07-27 14:35:15745parcourir

Producer-Consumer Pattern

Dans cet article, les Goroutines et les chaînes sont présentées. Ce sont deux des constructions les plus utiles du moment. Ensemble, lorsqu'ils sont utilisés correctement, ils offrent aux développeurs une grande flexibilité dans la gestion de la concurrence. C’est l’un des sujets les plus courants lors d’un entretien.

Mettre en œuvre un modèle simple de producteur-consommateur en déplacement.

var buffer = make(chan int, 5)

func produce(wg *sync.WaitGroup) {
    defer wg.Done()
    for i := 0; i < 10; i++ {
        buffer <- i
        time.Sleep(time.Millisecond * time.Duration(rand.Intn(100)))
    }
    fmt.Println("producer done")
}

func consume(wg *sync.WaitGroup) {
    defer wg.Done()
    for data := range buffer {
        fmt.Println(data)
        time.Sleep(time.Millisecond * time.Duration(rand.Intn(400)))
    }
    fmt.Println("consumer done")
}

func main() {
    var producerWg sync.WaitGroup
    var consumerWg sync.WaitGroup
    producerWg.Add(1)
    go produce(&producerWg)
    go func() {
        producerWg.Wait()
        close(buffer)
        fmt.Println("closed channel")
    }()
    consumerWg.Add(1)
    go consume(&consumerWg)
    consumerWg.Wait()
    fmt.Println("done")
}

C'est l'une des implémentations les plus simples ; mais le modèle est assez courant. Nous avons un fil qui « produit » les valeurs et un fil qui doit les « consommer ». En Golang, le moyen de transmettre ces valeurs entre les threads est un canal.

On commence par créer un canal pour les entiers. Créez ensuite les routines qui implémentent les fonctions de producteur et de consommateur.

Dans toute situation multithread, la synchronisation est un problème. Golang a créé WaitGroup comme moyen de mettre en œuvre la synchronisation. Ils fonctionnent simplement comme des compteurs et un thread qui doit se synchroniser attendra que le compte soit 0. Un thread de contrôle utilise la fonction Done() pour décrémenter le compteur.

Dans ce problème, nous créons un WaitGroup pour le producteur et le consommateur, en initialisant les deux au compte 1 (à l'aide de la fonction Add()).

Le thread principal lance le producteur, le consommateur et un thread en ligne qui attend le producteur puis attend que le consommateur termine.

Le thread producteur commence à envoyer des données normalement. Une fois terminé, il utilise le WaitGroup pour signaler qu'il a terminé l'envoi vers le canal. La goroutine en ligne attend le producteur WaitGroup qui ferme le canal. Si le canal n'est jamais fermé, le consommateur dormirait éternellement en attendant plus de données et le processus ne se terminerait jamais.

Lorsque le consommateur n'a plus de données (car le canal a été fermé), il informe le deuxième WaitGroup que c'est fait.

Le thread principal qui a lancé les threads producteur et consommateur attend que le WaitGroup consommateur lui permette de se terminer. Cela empêche le thread principal de se terminer prématurément, ce qui tuerait tous les threads du processus.

Ce n’est pas la seule façon de mettre en œuvre le modèle producteur-consommateur.

Il existe également certains problèmes tels que la terminaison externe de signaux tels que SIGTERM et SIGINT qui devraient être résolus pour le code de production. Il s'agit d'une démonstration simple qui montre les bases.

Comment le mettriez-vous en œuvre autrement ? Qu'est-ce qui manque dans l'implémentation ci-dessus ? Publiez vos commentaires ou liens vers d’autres implémentations ci-dessous.

Merci !

Le code de cet article et de tous les articles de cette série peut être trouvé ici

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