电脑什么软件做短视频网站,百度网站收录提交,房地产网站建设哪家有效果,国家备案查询目录 概述实践无缓冲 channel代码结果 缓冲 channel代码结果 channel的关闭特点代码结果range代码结果 select channel代码结果 结束 概述
此篇文章介绍 channel 的用法
无缓冲 channel缓冲 channelchannel的关闭特点range channelselect channel
每一种#xff0c;配上完整… 目录 概述实践无缓冲 channel代码结果 缓冲 channel代码结果 channel的关闭特点代码结果range代码结果 select channel代码结果 结束 概述
此篇文章介绍 channel 的用法
无缓冲 channel缓冲 channelchannel的关闭特点range channelselect channel
每一种配上完整的代码及相应的测试结果对关键的部分配置上图及对应说明。
实践
无缓冲 channel 未分配空间的 channel 具有 阻塞的功能。交互的 goroutine 两都都会阻塞的效果。 无缓充的 channel 总结如下
第1步两个 goroutine 都到达通道但都没有开始执行发送或接收第2步左侧的 goroutine 将手伸进了通道模拟了向通道发送数据的行为。此时这个 goroutine 会在通道中被锁住直道交换完成。第3步右侧 goroutine 将手放入通道模拟了从通道里接收数据。这个 goroutine 一样也会在通道中被锁住直到交换完成第4步与第5步进行交换。并最终在第6步两个 goroutine 都将手从通道里拿出来模拟了被锁住的 goroutine 得到释放。
代码
package mainimport fmtfunc main() {// 定义一个 channel,并没有分配空间c : make(chan int)// 匿名函数go func() {defer fmt.Println(goroutine调用结束...)fmt.Println(goroutine 正在运行...)c - 666}()num : -cfmt.Println(num:, num)fmt.Println(main goroutine 结束。。。)}结果
执行结果如下
缓冲 channel 第1步右侧的 goroutine 正在从通道接收一个值第2步右侧的这个 goroutine 独立 完成了 接收值 的动作而左侧的 goroutine 正在发送一个新值至通道里第3步左侧的 goroutine 还在向通道发送新值而右侧的 goroutine 正在从通道接收另外一个值。这两个步骤里的操作既不是同步的也不会相互阻塞。第4步所有的发送和接收都完成而通道里还有几个值也有一些空间可以存更多的值。
特点当 channel 已经满再向里面写数据就会阻塞当 channel 为空时从里面取数据也会阻塞。
代码
package mainimport (fmttime
)func main() {// 带有缓冲的 channelc : make(chan int, 3)fmt.Println(len(c) , len(c), ,cap(c), cap(c))go func() {defer fmt.Println(子goroutine执行结束...)for i : 0; i 4; i {c - ifmt.Println(子goroutine正在运行发送的元素, i, len(c) , len(c), ,cap(c), cap(c))}}()time.Sleep(2 * time.Second)for i : 0; i 4; i {num : -cfmt.Println(num, num)}fmt.Println(main 结束...)
}结果
执行结果如下
channel的关闭特点
channel 不像文件一样需要经常关闭只有确实没有任何发送数据了或者想显式的结束 range 循环之类的才去关闭 channel关闭 channel 后无法向 channel 再发送数据(引发 panic 错误后导致接收立即返回零值)关闭 channel 后可以继续从 channel 接收数据对于 nil channel 无论收发都会被阻塞
代码
package mainimport fmtfunc main() {c : make(chan int)go func() {for i : 0; i 5; i {c - i}// close可以关闭一个 channelclose(c)}()for {// ok 如果为true表示channel没有关闭如果为false表示channel已经关闭if data, ok : -c; ok {fmt.Println(data)} else {break}}fmt.Println(main finished...)
}结果
执行结果如下
range代码 range 写法完整代码如下 package mainimport fmtfunc main() {c : make(chan int)go func() {for i : 0; i 5; i {c - i}// close可以关闭一个 channelclose(c)}()// 可以使用 range 来迭代不断操作 channelfor data : range c {fmt.Println(data)}
}结果 range-channel 测试结果如下 select channel
代码
package mainimport fmtfunc main() {c : make(chan int)quit : make(chan int)go func() {for i : 0; i 5; i {fmt.Println(-c)}// close可以关闭一个 channelquit - 0}()x, y : 1, 1for {select {case c - x:// 如果 c 可写则该 case 会进来x yy x ycase -quit:fmt.Println(quit)return}}}结果 结束
Golang channel的 基本定义及使用 至此结束如有疑问欢迎评论区留言。