简介:介绍生产者消费者模型,及go简单实现的demo。一、生产者消费者模型生产者消费者模型:某个模块(函数等〉负责产生数据,这些数据由另一个模块来负责处理(此处的模块是广义的,可以是类、函数、协程、线程、进程等)。产生数据的模块,就形象地称为生产者;而处理数据的模块,就称为消费者。 假设你要寄一件快递,大致过程如下。. 这么看,有了缓冲区就有了以下好处: 二、Go语言实现单向channel最典型的应用是“生产者消费者模型”。channel又分为有缓冲和无缓冲channel。channel中参数传递的时候,是作为引用传递。 1、无缓冲channel示例代码一实现如下 package main import "fmt" func producer(out chan <- int) { for i:=0; i<10; i++{ data := i*i fmt.Println("生产者生产数据:", data) out <- data // 缓冲区写入数据 } close(out) //写完关闭管道 } func consumer(in <- chan int){ // 同样读取管道 //for{ // val, ok := <- in // if ok { // fmt.Println("消费者拿到数据:", data) // }else{ // fmt.Println("无数据") // break // } //} // 无需同步机制,先做后做 // 没有数据就阻塞等 for data := range in { fmt.Println("消费者得到数据:", data) } } func main(){ // 传参的时候显式类型像隐式类型转换,双向管道向单向管道转换 ch := make(chan int) //无缓冲channel go producer(ch) // 子go程作为生产者 consumer(ch) // 主go程作为消费者 } 这里使用无缓冲channel,生产者生产一次数据放入channel,然后消费者从channel读取数据,如果没有只能等待,也就是阻塞,直到管道被关闭。所以宏观是生产者消费者同步执行。 2、有缓冲channel示例代码二如下 package main import "fmt" func producer(out chan <- int) { for i:=0; i<10; i++{ data := i*i fmt.Println("生产者生产数据:", data) out <- data // 缓冲区写入数据 } close(out) //写完关闭管道 } func consumer(in <- chan int){ // 无需同步机制,先做后做 // 没有数据就阻塞等 for data := range in { fmt.Println("消费者得到数据:", data) } } func main(){ // 传参的时候显式类型像隐式类型转换,双向管道向单向管道转换 ch := make(chan int, 5) // 添加缓冲区,5 go producer(ch) // 子go程作为生产者 consumer(ch) // 主go程作为消费者 } 有缓冲channel,只修改 三、实际应用实际应用中,同时访问同一个公共区域,同时进行不同的操作。都可以划分为生产者消费者模型,比如订单系统。 代码示例三如下 package main import ( "fmt" "time" ) // 模拟订单对象 type OrderInfo struct { id int } // 生产订单--生产者 func producerOrder(out chan <- OrderInfo) { // 业务生成订单 for i:=0; i<10; i++{ order := OrderInfo{id: i+1} fmt.Println("生成订单,订单ID为:", order.id) out <- order // 写入channel } // 如果不关闭,消费者就会一直阻塞,等待读 close(out) // 订单生成完毕,关闭channel } // 处理订单--消费者 func consumerOrder(in <- chan OrderInfo) { // 从channel读取订单,并处理 for order := range in{ fmt.Println("读取订单,订单ID为:", order.id) } } func main() { ch := make(chan OrderInfo, 5) go producerOrder(ch) go consumerOrder(ch) time.Sleep(time.Second * 2) } 这里如上面逻辑类似,不同的是用一个,OrderInfo结构体模拟订单作为业务处理对象。主线程使用 文章来源:https://www.cnblogs.com/welan/archive/2021/11/21/15585536.html |
|