首页 > 后端开发 > Golang > 正文

生产者/消费者

王林
发布: 2024-07-24 11:51:42
原创
247 人浏览过

定义

我们考虑两个进程,分别称为“生产者”和“消费者”。生产者是一个循环过程,每次循环都会产生一定部分的信息,这些信息必须由消费者处理。消费者也是一个循环过程,每次它经历它的周期时,它都可以处理下一条信息,因为它是由生产者产生的。计算过程给出了一个简单的例子,该计算过程生成由穿孔卡打孔的穿孔卡的“信息部分”图像,穿孔卡扮演消费者的角色。[1]

Producer/Consumer (Produtor/Consumidor)

解释

生产者创建项目并将其存储在数据结构中,而消费者则从该结构中删除项目并处理它们。

如果消费大于生产,则缓冲区(数据结构)清空,消费者没有任何东西可消费
如果消耗量 小于 生产量,则缓冲区已满,生产者无法添加更多项目。这是一个经典问题,称为有限缓冲区

问题的情境化

假设我们有一个生产者在缓冲区中发布一封电子邮件,以及一个消费者使用缓冲区中的电子邮件并显示一条消息,表明已发送电子邮件并通知电子邮件的新访问密码。

执行

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


登录后复制

解释实施

  • 首先,我们创建一个名为 buffer 的结构,其中包含一个名为 items 的字符串数组和一个名为 mu 的类似互斥体的控制机制,用于管理并发访问。
  • 我们有两个函数:一个称为 add,它基本上将一个项目添加到缓冲区中,只要有可用空间,因为缓冲区容量只有 5 个项目;另一个 get 调用,如果缓冲区中有项目,则返回第一个元素并从缓冲区中删除该元素。
  • Producer 基本上从循环中获取索引,并将其连接成一个名为 str 的字符串,其中包含索引和虚拟电子邮件域,并将其添加到缓冲区。添加了时间间隔来模拟延迟。
  • 消费者从缓冲区请求一个项目(如果它至少有一个项目)。然后,消费者在屏幕上显示一条消息,通知已发送一封电子邮件,其中包含缓冲区中发布的项目的新访问密码。

代码链接: https://github.com/jcelsocosta/race_condition/blob/main/ Producerconsumer/buffer/ Producerconsumer.go

参考

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

参考书目

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

以上是生产者/消费者的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:dev.to
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责声明 Sitemap
PHP中文网:公益在线PHP培训,帮助PHP学习者快速成长!