定义
我们考虑两个流程,分别称为“生产者”和“消费者”。生产者是一个循环过程,每次循环都会产生一定部分的信息,这些信息必须由消费者处理。消费者也是一个循环过程,每次它经历它的周期时,它都可以处理下一条信息,因为它是由生产者产生的。计算过程给出了一个简单的例子,该计算过程生成由穿孔卡打孔的穿孔卡的“信息部分”图像,穿孔卡扮演消费者的角色。[1]
解释
生产者创建项目并将其存储在数据结构中,而消费者从该结构中删除项目并处理它们。
如果消费大于生产,则缓冲区(数据结构)清空,消费者没有什么可消费的
如果消耗量小于生产量,则缓冲区已满,生产者无法添加更多项目。这是一个经典问题,称为有限缓冲区。
问题的情境化
假设我们有一个生产者在缓冲区中发布一封电子邮件,以及一个消费者使用缓冲区中的电子邮件并显示一条消息,说明已使用所提供的电子邮件的新访问密码发送了一封电子邮件。 ]
去实施
包主
进口 (
“FMMT”
“你”
“strcon”
“同步”
“团队”
)
类型缓冲区结构 {
项目[]字符串
mu同步互斥体
}
func (buff *buffer) add(项目字符串) {
buff.mu.Lock()
延迟 buff.mu.Unlock()
if len(buff.items)
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)
解释实施
首先,我们创建一个名为 - buffer 的结构,其中包含一个名为 items 的字符串数组和一个名为 mu 的类似互斥体的控制机制,用于管理并发访问。
我们有两个函数:一个称为 add,它基本上将一个项目添加到缓冲区中,只要有可用空间,因为缓冲区容量只有 5 个项目;另一个 get 调用,如果缓冲区中有项目,则返回第一个元素并从缓冲区中删除该元素。-
- Producer 基本上从循环中获取索引,并将其连接成一个名为 str 的字符串,其中包含索引和虚拟电子邮件域,并将其添加到缓冲区。添加了时间间隔来模拟延迟。
- 消费者从缓冲区请求一个项目(如果它至少有一个项目)。然后,消费者在屏幕上显示一条消息,通知已发送一封电子邮件,其中包含缓冲区中发布的项目的新访问密码。
代码链接: https://github.com/jcelsocosta/race_condition/blob/main/ Producerconsumer/buffer/ Producerconsumer.go
参考
https://www.cs.utexas.edu/~EWD/transcriptions/EWD01xx/EWD123.html#4.1。通用信号量的典型用途。-
参考书目
https://www.cin.ufpe.br/~cagf/if677/2015-2/slides/08_Concorrencia (Jorge).pdf