有一个并发的 Go 协程来向chan写入数据,而 Go 主协程负责读取(接收)数据。
Go 主协程中创建了容量为 100 的chan队列 ch,而第 25 行把 ch 传递给了 write 协程。接下来 Go 主协程休眠了2秒。
在这期间,write 协程在并发地运行。write 协程有一个 for 循环,依次向chan队列 ch 写入 0~47,然后休眠0.3秒。而缓冲chan的容量为 100,如果写满100,则发生阻塞,直到 ch 内的值被读取。
读取操作每次读取前先判断缓存chan队列ch中缓存的元素数量。
如果没有缓冲元素则休眠0.2秒。
如果有缓冲元素,则判断缓冲元素个数len(ch)是否大于MAXREQLEN (30)。如果len(ch)>30,则一个批次读取30个元素,否则一个批次读取len(ch)个元素。
读取到元素后,do some thing,然后继续读取。
package main
import (
"fmt"
"time"
)
var MAXREQLEN = 30
func write(ch chan int) {
for {
for i := 0; i < 47; i++ {
ch <- i
fmt.Println("successfully wrote", i, "to ch")
}
time.Sleep(300 * time.Millisecond)
}
//close(ch)
}
func main() {
//test()
ch := make(chan int, 100)
go write(ch)
time.Sleep(2 * time.Second)
for {
numArr := make([]int, 0)
bufferChan := len(ch)
if bufferChan > 0 {
var max int
if bufferChan > MAXREQLEN {
max = MAXREQLEN
} else {
max = bufferChan
}
for i := 0; i < max; i++ {
v := <-ch
fmt.Println("read value", v, "from ch")
numArr = append(numArr, v)
}
fmt.Println(numArr)
fmt.Println("do some thing")
}
time.Sleep(200 * time.Millisecond)
fmt.Println("Sleep(100 * time.Millisecond)")
}
}
func test() {
c := make(chan int, 100)
fmt.Println("1.len:", len(c))
for i := 0; i < 34; i++ {
c <- 0
}
fmt.Println("2.len:", len(c))
<-c
<-c
fmt.Println("3.len:", len(c))
}