我们本篇博文主要通过几个例子来介绍生产者消费者模型。
案例一
生产者协程
// 生产商品
go func() {
for {
productId := strconv.Itoa(time.Now().Nanosecond())
chanShop <- "商品" + productId
fmt.Println("生产了商品", productId)
time.Sleep(time.Second)
}
}()
消费者协程
// 消费商品
go func() {
for {
product := <- chanShop
fmt.Println("消费了商品", product)
time.Sleep(time.Second)
}
}()
主程序任务等待
// 主程序
for {
time.Sleep(time.Second)
}
完整案例
// 生产者消费者模型之源源不断的生产消费,生产消费
package main
import (
"fmt"
"strconv"
"time"
)
func main() {
chanShop := make(chan string)
// 生产商品
go func() {
for {
productId := strconv.Itoa(time.Now().Nanosecond())
chanShop <- "商品" + productId
fmt.Println("生产了商品", productId)
time.Sleep(time.Second)
}
}()
// 消费商品
go func() {
for {
product := <- chanShop
fmt.Println("消费了商品", product)
time.Sleep(time.Second)
}
}()
// 主程序
for {
time.Sleep(time.Second)
}
}
案例二
此案例引入一个”物流“的概念,完成对他的生产消费。
chan定义
// 定义中转物流仓库,定义存储100个上商品
chanStorage := make(chan string, 100)
// 定义消费渠道,由消费者进行消费
chanSell := make(chan string, 100)
producer生产者
// 制造商品,producer
go func() {
for i := 0; i < 10; i++ {
product := strconv.Itoa(time.Now().Nanosecond())
chanStorage <- "商品:" + product
fmt.Println("生产了商品", product)
}
close(chanStorage)
}()
物流中转
// 进行中转托运
go func() {
for p := range chanStorage{
chanSell <- p
fmt.Println("完成了中转托运", p)
}
fmt.Println("商品转运完成! 商店关闭!")
close(chanSell)
}()
消费者 comsumer
// 进行售卖商品, comsumer
go func() {
for sellerP := range chanSell{
fmt.Println("消费了商品", sellerP)
fmt.Println()
}
fmt.Println("商品已经全部消费完成!")
}()
主协程等待
// 主流程
for {
time.Sleep(time.Second)
}
完整案例
// 生产者消费者模型之中转物流
package main
import (
"fmt"
"strconv"
"time"
)
func main() {
// 定义中转物流仓库,定义存储100个上商品
chanStorage := make(chan string, 100)
// 定义消费渠道,由消费者进行消费
chanSell := make(chan string, 100)
// 制造商品,producer
go func() {
for i := 0; i < 10; i++ {
product := strconv.Itoa(time.Now().Nanosecond())
chanStorage <- "商品:" + product
fmt.Println("生产了商品", product)
}
close(chanStorage)
}()
// 进行中转托运
go func() {
for p := range chanStorage{
chanSell <- p
fmt.Println("完成了中转托运", p)
}
fmt.Println("商品转运完成! 商店关闭!")
close(chanSell)
}()
// 进行售卖商品, comsumer
go func() {
for sellerP := range chanSell{
fmt.Println("消费了商品", sellerP)
fmt.Println()
}
fmt.Println("商品已经全部消费完成!")
}()
// 主流程
for {
time.Sleep(time.Second)
}
}
抽离函数式进阶
// 生产者消费者模型之中转物流
package main
import (
"fmt"
"strconv"
"time"
)
// 定义producer
func producer(chanStorage chan string) {
for i := 0; i < 10; i++ {
product := strconv.Itoa(time.Now().Nanosecond())
chanStorage <- "商品:" + product
fmt.Println("生产了商品", product)
}
close(chanStorage)
}
// 定义中转效果
func logisic(chanStorage, chanSell chan string) {
for p := range chanStorage{
chanSell <- p
fmt.Println("完成了中转托运", p)
}
fmt.Println("商品转运完成! 商店关闭!")
close(chanSell)
}
// 定义消费者
func consumer(chanSell chan string) {
for sellerP := range chanSell{
fmt.Println("消费了商品", sellerP)
fmt.Println()
}
fmt.Println("商品已经全部消费完成!")
}
func main() {
// 定义中转物流仓库,定义存储100个上商品
chanStorage := make(chan string, 100)
// 定义消费渠道,由消费者进行消费
chanSell := make(chan string, 100)
// 制造商品,producer
go producer(chanStorage)
// 进行中转托运
go logisic(chanStorage, chanSell)
// 进行售卖商品, comsumer
go consumer(chanSell)
// 主流程
for {
time.Sleep(time.Second)
}
}
结果展示
完成了中转托运 商品:524589000
消费了商品 商品:524589000
生产了商品 524589000
生产了商品 525884000
生产了商品 525890000
生产了商品 525892000
生产了商品 525893000
生产了商品 525894000
生产了商品 525895000
生产了商品 525896000
生产了商品 525897000
生产了商品 525898000
完成了中转托运 商品:525884000
完成了中转托运 商品:525890000
完成了中转托运 商品:525892000
完成了中转托运 商品:525893000
完成了中转托运 商品:525894000
完成了中转托运 商品:525895000
完成了中转托运 商品:525896000
完成了中转托运 商品:525897000
完成了中转托运 商品:525898000
商品转运完成! 商店关闭!
消费了商品 商品:525884000
消费了商品 商品:525890000
消费了商品 商品:525892000
消费了商品 商品:525893000
消费了商品 商品:525894000
消费了商品 商品:525895000
就能够只读取管道里面的商品。