Maison > développement back-end > Golang > le corps du texte

Producteur/Consommateur

王林
Libérer: 2024-07-24 11:51:42
original
247 Les gens l'ont consulté

Définition

Nous considérons deux processus, appelés respectivement « producteur » et « consommateur ». Le producteur est un processus cyclique et chaque fois qu'il parcourt son cycle, il produit une certaine partie d'informations qui doivent être traitées par le consommateur. Le consommateur est également un processus cyclique et chaque fois qu'il parcourt son cycle, il peut traiter l'information suivante, telle qu'elle a été produite par le producteur. Un exemple simple est donné par un processus informatique, qui produit sous forme de « portions d’information » des images de cartes perforées devant être perforées par une carte perforée, qui joue le rôle du consommateur.[1]

Producer/Consumer (Produtor/Consumidor)

Explication

Un producteur crée des éléments et les stocke dans une structure de données, tandis qu'un consommateur supprime des éléments de cette structure et les traite.

Si la consommation est supérieure à la production, le tampon (structure de données) se vide, et le consommateur n'a rien à consommer
Si la consommation est inférieure à la production, le tampon se remplit et le producteur ne peut pas ajouter d'articles supplémentaires. Il s'agit d'un problème classique appelé tampon limité.

Contextualisation du problème

Supposons que nous ayons un producteur qui publie un e-mail dans le tampon et un consommateur qui consomme l'e-mail du tampon et affiche un message indiquant qu'un e-mail a été envoyé avec le nouveau mot de passe d'accès à l'e-mail informé.

Aller à la mise en œuvre

package main

import (
    "fmt"
    "os"
    "strconv"
    "sync"
    "time"
)

type buffer struct {
    items []string
    mu    sync.Mutex
}

func (buff *buffer) add(item string) {
    buff.mu.Lock()
    defer buff.mu.Unlock()
    if len(buff.items) < 5 {
        buff.items = append(buff.items, item)
        // fmt.Println("Foi adicionado o item " + item)
    } else {
        fmt.Println("O Buffer não pode armazenar nenhum item mais está com a capacidade máxima")
        os.Exit(0)
    }
}

func (buff *buffer) get() string {
    buff.mu.Lock()
    defer buff.mu.Unlock()
    if len(buff.items) == 0 {
        return ""
    }
    target := buff.items[0]

    buff.items = buff.items[1:]
    return target
}

var wg sync.WaitGroup

func main() {
    buff := buffer{}
    wg.Add(2)

    go producer(&buff)
    go consumer(&buff)
    wg.Wait()
}

func producer(buff *buffer) {
    defer wg.Done()
    for index := 1; ; index++ {
        str := strconv.Itoa(index) + "@email.com"
        buff.add(str)
        time.Sleep(5 * time.Millisecond) // Adiciona um pequeno atraso para simular produção
    }
}

func consumer(buff *buffer) {
    defer wg.Done()
    for {
        data := buff.get()

        if data != "" {
            fmt.Println("Enviado um email com a nova senha de acesso para: " + data)
        }
    }
}


Copier après la connexion
Expliquer la mise en œuvre

    Tout d'abord, nous créons une structure appelée
  • buffer, qui contient un tableau de chaînes appelées items et un mécanisme de contrôle de type mutex, appelé mu, pour gérer les accès simultanés.
  • Nous avons deux fonctions : l'une appelée add, qui ajoute essentiellement un élément au tampon, tant qu'il y a de l'espace disponible, puisque la capacité du tampon n'est que de 5 éléments ; et un autre appel get, qui, s'il y a des éléments dans le tampon, renvoie le premier élément et supprime cet élément du tampon.
  • Le
  • Producer prend essentiellement l'index de la boucle et le concatène en une chaîne appelée str, qui contient l'index et un domaine de messagerie factice, et l'ajoute au tampon. Un intervalle de temps a été ajouté pour simuler un retard.
  • Consumer demande un élément au tampon, s'il contient au moins un élément. Le Consommateur affiche alors un message à l'écran l'informant qu'un email a été envoyé avec le nouveau mot de passe d'accès à l'élément qui a été publié dans le buffer.

Lien du code : https://github.com/jcelsocosta/race_condition/blob/main/producerconsumer/buffer/producerconsumer.go

Référence

    https://www.cs.utexas.edu/~EWD/transcriptions/EWD01xx/EWD123.html#4.1.%20Typical%20Uses%20of%20the%20General%20Semaphore.
Bibliographie

https://www.cin.ufpe.br/~cagf/if677/2015-2/slides/08_Concorrencia%20(Jorge).pdf

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!

source:dev.to
Déclaration de ce site Web
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
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!