假设我们会利用协程向通道内添加动态数量的数据,然后我们利用循环一直取出数据,直至取完。
package main
func main() {
ch := make(chan int)
// 开启一个协程
go func() {
for i := 1; i <= 10; i++ {
ch <- i
}
}()
for {
// 此处因为管道没有关闭,会产生阻塞
res, ok := <-ch
if ok {
println(res)
} else {
break
}
}
println("主进程结束")
}
上面的代码中,我们并不知道何时取完数据,然后 for 循环在取出 10 条数据后报错!
1
2
3
4
5
6
7
8
9
10
fatal error: all goroutines are asleep - deadlock!
package main
func main() {
ch := make(chan int)
// 开启一个协程
go func() {
for i := 1; i <= 10; i++ {
ch <- i
}
close(ch)
}()
for {
res, ok := <-ch
if ok {
println(res)
} else {
break
}
}
println("主进程结束")
}
在上面的代码中,我们使用 close 函数关闭了通道,这样 res,ok := <-ch 代码运行,当管道关闭时 ok 的值会为 false,我们利用 break 跳出循环,逻辑将不会阻塞。
当我们再次需要向 ch 中存入数据时,我们可以将 ch 赋值为一个新的通道:
ch = make(chan int)