Go开发 Channel彻底研究(一)无缓冲

从这篇开始做一个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

标签:收发   题目   信号   通道   原理   形式   结束   代码   程序   数据

1 2 3 4 5

上滑加载更多 ↓
推荐阅读:
友情链接:
更多:

本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828  

© CopyRight 2020-2024 All Rights Reserved. Powered By 71396.com 闽ICP备11008920号-4
闽公网安备35020302034903号

Top