Producer/Consumer

王林
Release: 2024-07-24 11:51:42
Original
231 people have browsed it

Definition

We consider two processes, called “producer” and “consumer”, respectively. The producer is a cyclical process and each time it goes through its cycle it produces a certain portion of information, which must be processed by the consumer. The consumer is also a cyclical process and each time it goes through its cycle it can process the next piece of information, as it was produced by the producer. A simple example is given by a computational process, which produces as “portions of information” images of punched cards to be punched by a punched card, which plays the role of the consumer.[1]

Producer/Consumer (Produtor/Consumidor)

Explanation

A producer creates items and stores them in a data structure, while a consumer removes items from that structure and processes them.

If consumption is greater than production, the buffer (data structure) empties, and the consumer has nothing to consume
If consumption is less than production, the buffer fills up, and the producer is unable to add more items. This is a classic problem called limited buffer.

Contextualization of the Problem

Suppose we have a producer that publishes an email in the buffer, and a consumer that consumes the email from the buffer and displays a message stating that an email was sent with the new access password for the email entered .

Go implementation

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


Copy after login
e

Explaining the implementation

  • First, we create a structure called buffer, which contains an array of strings called items and a mutex-like control mechanism, called mu, to manage concurrent access.
  • We have two functions: one called add, which basically adds an item to the buffer, as long as there is space available, since the buffer capacity is only 5 items; and another get call, which, if there are items in the buffer, returns the first element and removes that element from the buffer.
  • The Producer basically takes the index from the loop and concatenates it into a string called str, which contains the index and a dummy email domain, and adds it to the buffer. A time gap has been added to simulate a delay.
  • The Consumer requests an item from the buffer, if it has at least one item. The Consumer then displays a message on the screen informing that an email was sent with the new access password for the item that was published in the buffer.

Code link: https://github.com/jcelsocosta/race_condition/blob/main/producerconsumer/buffer/producerconsumer.go

Reference

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

Bibliography

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

The above is the detailed content of Producer/Consumer. For more information, please follow other related articles on the PHP Chinese website!

source:dev.to
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!