内容简介:双层通道的解释见以下是一个双层通道的使用示例。注意下面的示例中使用了"信号通道"(Signal channel),但这里的信号通道是多余的,仅仅只是为了介绍。上面的示例中,函数f1()两个参数,一个是双层通道cc,一个是信号通道f。f1()中首先生成了一个通道c,并发送给了双层通道cc,使得main()中可以从cc中取得这个内层通道c,并向其发送数据。
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()可以取得这个计算结果。
上面的示例中有几个细节需要注意:
- 在f1()中必须关闭内层通道c,因为main()中的range迭代一个未关闭的通道会一直阻塞,而且每次调用f1()都会重新创建c通道。
- 上面的信号通道其实没有起到任何作用。
- f1()中的select必须不能放进for循环。因为f1()将数据发回c之后,如果在for中,发f()所在的goroutine将阻塞在select上,由于c通道还没有关闭,这会导致main goroutine因range迭代操作而阻塞,也就是说所有goroutine都被阻塞了,出现了死锁。
所以,当在select中有发送操作的时候,很可能会出现死锁现象。这时, 要么为select加上default,要么为select加上超时时间,要么select不要放在for循环中 。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
React Native开发指南
[美]艾森曼 / 黄为伟 / 人民邮电出版社 / 2016-6-1 / CNY 59.00
本书通过丰富的示例和详细的讲解,介绍了React Native这款JavaScript框架。在React Native中利用现有的JavaScript和React知识,就可以开发和部署功能完备的、真正原生的移动应用,并同时支持iOS与Android平台。除了框架本身的概念讲解之外,本书还讨论了如何使用第三方库,以及如何编写自己的Java或Objective-C的React Native扩展。一起来看看 《React Native开发指南》 这本书的介绍吧!