我们考虑两个进程,分别称为“生产者”和“消费者”。生产者是一个循环过程,每次循环都会产生一定部分的信息,这些信息必须由消费者处理。消费者也是一个循环过程,每次它经历它的周期时,它都可以处理下一条信息,因为它是由生产者产生的。计算过程给出了一个简单的例子,该计算过程生成由穿孔卡打孔的穿孔卡的“信息部分”图像,穿孔卡扮演消费者的角色。[1]
生产者创建项目并将其存储在数据结构中,而消费者则从该结构中删除项目并处理它们。
如果消费大于生产,则缓冲区(数据结构)清空,消费者没有任何东西可消费
如果消耗量 小于 生产量,则缓冲区已满,生产者无法添加更多项目。这是一个经典问题,称为有限缓冲区。
假设我们有一个生产者在缓冲区中发布一封电子邮件,以及一个消费者使用缓冲区中的电子邮件并显示一条消息,表明已发送电子邮件并通知电子邮件的新访问密码。
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) } } }
代码链接: https://github.com/jcelsocosta/race_condition/blob/main/ Producerconsumer/buffer/ Producerconsumer.go
https://www.cin.ufpe.br/~cagf/if677/2015-2/slides/08_Concorrencia%20(Jorge).pdf
以上是生产者/消费者的详细内容。更多信息请关注PHP中文网其他相关文章!