生产者消费者模型 '基于go实现'
基于 Channel 编写一个简单的单线程生产者消费者模型: 队列: 队列长度 10,队列元素类型为 int 生产者: 每 1 秒往队列中放入一个类型为 int 的元素,消费者: 每一秒从队列中获取一个元素并打印。
1.生产者消费者问题
版本1 未添加wait控制
package main
import (
"fmt"
"time"
)
func product(ch chan int) {
for {
ch <- 1
time.Sleep(time.Second)
fmt.Println("ch put:", 1)
}
}
func custom(ch chan int) {
for v := range ch {
time.Sleep(time.Second)
fmt.Println("ch get:", v)
}
}
func main() {
fmt.Println("main start product and custom problom")
ch := make(chan int, 10)
go product(ch)
go custom(ch)
time.Sleep(30 * time.Second)
}
版本2 添加wait控制
package main
import (
"fmt"
"sync"
"time"
)
func product(ch chan int, wg *sync.WaitGroup) {
defer wg.Done()
for {
ch <- 1
time.Sleep(time.Second)
fmt.Println("ch put:", 1)
}
}
func custom(ch chan int, wg *sync.WaitGroup) {
defer wg.Done()
for v := range ch {
time.Sleep(time.Second)
fmt.Println("ch get:", v)
}
}
func main() {
fmt.Println("main start product and custom problem")
ch := make(chan int, 10)
var wg sync.WaitGroup
wg.Add(2)
go product(ch, &wg)
go custom(ch, &wg)
wg.Wait()
close(ch)
fmt.Println("main exit")
}
版本3 不添加wait控制
package main
import (
"fmt"
"time"
)
func producer(queue chan int) {
for i := 0; ; i++ {
queue <- i
fmt.Printf("product get %d\n", i)
time.Sleep(time.Second)
}
}
func consumer(queue chan int) {
for {
item := <-queue
fmt.Printf("custom get %d\n", item)
time.Sleep(time.Second)
}
}
func main() {
queue := make(chan int, 10)
go producer(queue)
consumer(queue)
}
2.添加条件当channel为空或为满时阻塞
基于 Channel 编写一个简单的单线程生产者消费者模型: 队列: 队列长度 10,队列元素类型为 int 生产者: 每 1 秒往队列中放入一个类型为 int 的元素,队列满时输出product full 消费者: 每一秒从队列中获取一个元素并打印,队列为空时输出custom null。
package main
import (
"fmt"
"time"
)
func main() {
ch := make(chan int, 10) // 设置缓冲区大小为1
go func() {
for i := 0; ; i++ {
val := i
select { //如果通道已经存满,就会执行 default
// 写数据
case ch <- val:
fmt.Printf("put %d into channel\n", val)
time.Sleep(500 * time.Millisecond)
default:
time.Sleep(time.Second)
fmt.Println("channel full")
}
}
}()
for {
select { //如果通道已经存满,就会执行 default
// 写数据
case val := <-ch:
fmt.Printf("get %d out of channel\n", val)
time.Sleep(time.Second)
default:
time.Sleep(time.Second)
fmt.Println("channel null")
}
}
}