• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

Go基础系列:双层channel用法示例

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

Go channel系列

双层通道的解释见Go的双层通道

以下是一个双层通道的使用示例。注意下面的示例中使用了"信号通道"(Signal channel),但这里的信号通道是多余的,仅仅只是为了介绍。

信号通道不用来传递数据,而是用来传递消息,用来产生可读、可写的事件,以便让select选中某个分支。产生消息事件的方式有多种,比如直接关闭通道、发送false/true布尔值等等

package main

import (
	"fmt"
	"time"
)

func main() {
	// 定义双层通道cc
	cc := make(chan chan int)
	times := 5
	for i := 1; i < times+1; i++ {
		// 定义信号通道f
		f := make(chan bool)

		// 每次循环都在双层通道cc中生成内层通道c
		// 并通过信号通道f来终止f1()
		go f1(cc, f)

		// 从双层通道cc中取出内层通道ch
		// 并向ch通道发送数据
		ch := <-cc
		ch <- i

		// 从ch中取出数据
		for sum := range ch {
			fmt.Printf("Sum(%d)=%d\n", i, sum)
		}
		// 每个循环睡眠一秒钟
		time.Sleep(time.Second)
		// 每次循环都关闭信号通道f
		close(f)
	}
}

// 双层通道cc用来生成内层通道c
// 并使用信号通道f来终止函数f1()
func f1(cc chan chan int, f chan bool) {
	c := make(chan int)
	cc <- c
	defer close(c)
	sum := 0
	select {
	// 从内层通道中取出数据,计算和,然后发回内层通道
	case x := <-c:
		for i := 0; i <= x; i++ {
			sum = sum + i
		}
		// goroutine将阻塞在此,直到数据被读走
		c <- sum
	// 信号通道f可读时,结束f1()的运行
	// 但因为select没有在for中,该case分支用不上
	case <-f:
		return
	}
}

上面的示例中,函数f1()两个参数,一个是双层通道cc,一个是信号通道f。f1()中首先生成了一个通道c,并发送给了双层通道cc,使得main()中可以从cc中取得这个内层通道c,并向其发送数据。

回到f1()中,select最初会被阻塞,因为内层通道c和信号通道f都没有数据可读。由于main()可以取得内层通道c,并向其发送数据,使得f1()中的select第一个case分支被选中,该分支会计算发送的整数之前的总和,并将计算结果重新发送给内层通道c,让main()可以取得这个计算结果。

上面的示例中有几个细节需要注意:

  1. 在f1()中必须关闭内层通道c,因为main()中的range迭代一个未关闭的通道会一直阻塞,而且每次调用f1()都会重新创建c通道。
  2. 上面的信号通道其实没有起到任何作用。
  3. f1()中的select必须不能放进for循环。因为f1()将数据发回c之后,如果在for中,发f()所在的goroutine将阻塞在select上,由于c通道还没有关闭,这会导致main goroutine因range迭代操作而阻塞,也就是说所有goroutine都被阻塞了,出现了死锁。

所以,当在select中有发送操作的时候,很可能会出现死锁现象。这时,要么为select加上default,要么为select加上超时时间,要么select不要放在for循环中


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
字节跳动年薪50W抢Go开发人才,你还在问该不该学?发布时间:2022-07-10
下一篇:
使用go语言遇到的一些问题记录发布时间:2022-07-10
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap