从这篇开始做一个channel的系列,改变从前的写作思路,不再写原理,而是通过做题来反证原理。
题目:创建无缓冲通道,主协程发,子协程收,然后退出程序
参考代码:
//创建通道
ch := make(chan int)
go func() {
<-ch //收
}()
ch <- 0 //发
fmt.Println("程序退出")
源码分析
这道题是最基本的收发形式,主协程发送时,由于阻塞,只有等到子协程执行<-ch时,主协程才解除阻塞。
模型
再看下接和收。
关键点:无缓冲通道必须收发都在场,如果有一方不在(比如忙)那么另一方就会阻塞,两者是同步传输数据。通俗的说,就是我发一个你接一个,我再发一个,你再接收一个,一个时刻就是一对收发存在。层次清楚,绝对不会乱。虽貌似简单,但也需要认真体会。
题目:主协程发送多个打印数据到子协程,子协程打印完成之后,再通知主协程结束
参考代码:
ch := make(chan int)
go func() {
for {
data := <-ch
if data == 0 {
break
}
fmt.Println("收数据", data)
}
//发送打印结束信号
fmt.Println("打印数据结束!")
ch <- 0
}()
for i := 1; i <= 3; i++ {
ch <- i
}
//发送结束信号
ch <- 0
//等
<-ch
fmt.Println("程序退出!")
源码分析
这个代码不完善,只用了一种比较笨拙的形式,主要用来说明原理。
先看发方,通过for循环发送三个数据,有些同学可能会随着联想认为,这三个数据是一下子倒进channel的,而实际是一对一的。参考上一题的总结,我们需要用一对一的思路来看,那就是,发送方发一个,接收方就接一个,三次循环,就是三次握手。
发送数据之后,发送方接着就发送了一个信号0,那么这又是一对接发的过程,如果接方忙,那发方就阻塞。
再看接收方,当收到信号0时退出循环,然后又向管道发送信号0,此时,原来的发送方也在等。两者又配对成接发。
当主协程最后等到数据时,程序结束。
模型
这个题目说明,一个管子可以两头对发,因为一对一严格配对执行,所以不会乱。
写了两道题,主要介绍channel的基本用法,下一篇继续研究
页面更新:2024-05-30
本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828
© CopyRight 2020-2024 All Rights Reserved. Powered By 71396.com 闽ICP备11008920号-4
闽公网安备35020302034903号