几点注意:go的无缓存通道

通道make 创建后,即使里面是空的,也可以取里面内容。但是程序会被阻塞。

通道的规则是没人取,是不能往里面放的。放的线程会阻塞。

最外层的requestChan相当于一个总线或媒介。

生产者goroutineD直接从requestChan通道里面再取一个内部通道responseChan,这时不管responseChan创建没有,如果没有的话会阻塞,直到取到后,往responseChan通道里面扔内容。

消费者goroutineC创建一个内部通道responseChan,然后就可以提取里面的内容。如果没有阻塞直到收到。

收取开始后,requestChan中介通道里面就没有responseChan内部通道了?

package main

import "fmt"
import "time" func main() { // make the request chan chan that both go-routines will be given
requestChan := make(chan chan string) // start the goroutines
go goroutineC(requestChan)
go goroutineD(requestChan) // sleep for a second to let the goroutines complete
time.Sleep( * time.Second) } func goroutineC(requestChan chan chan string) {
time.Sleep( * time.Second) fmt.Println("goroutineC create response chan.")
// make a new response chan
responseChan := make(chan string) // send the responseChan to goRoutineD
requestChan <- responseChan fmt.Println("goroutineC waiting to read.")
// read the response
response := <-responseChan fmt.Println("goroutineC get Response: ", response) } func goroutineD(requestChan chan chan string) { // read the responseChan from the requestChan
fmt.Println("\t\tgoroutineD wait to get response chan.")
responseChan := <-requestChan
fmt.Println("\t\tgoroutineD has gotten response chan.")
fmt.Println("\t\tgoroutineD sleep 5 minutes.")
time.Sleep( * time.Second)
// send a value down the responseChan
fmt.Println("\t\tgoroutineD send wassup.")
responseChan <- "wassup!" }

改成如下代码执行,发现通道的内容生成好之后也无法放入通道,需要有人取内容时,才能放入。这是go的无缓存通道规则

package main

import "fmt"
import "time" func main() { // make the request chan chan that both go-routines will be given
requestChan := make(chan chan string) // start the goroutines
go goroutineC(requestChan)
go goroutineD(requestChan) // go goroutineC(requestChan)
// go goroutineD(requestChan) // sleep for a second to let the goroutines complete
time.Sleep( * time.Second) } func goroutineC(requestChan chan chan string) { fmt.Println("goroutineC create response chan.")
// make a new response chan responseChan := make(chan string) // send the responseChan to goRoutineD
requestChan <- responseChan fmt.Println("goroutineC waiting to read.")
// read the response
response := <-responseChan fmt.Println("goroutineC get Response: ", response) ////read again/////////
// read the response
response = <-responseChan fmt.Println("goroutineC get Response: ", response) } func goroutineD(requestChan chan chan string) {
time.Sleep( * time.Second)
// read the responseChan from the requestChan
fmt.Println("\t\tgoroutineD wait to get response chan.")
responseChan := <-requestChan
fmt.Println("\t\tgoroutineD has gotten response chan.")
fmt.Println("\t\tgoroutineD sleep 5 minutes.")
time.Sleep( * time.Second)
// send a value down the responseChan
fmt.Println("\t\tgoroutineD send wassup.")
responseChan <- "wassup!" /////Send again to check if response chan dissapear///////////////
fmt.Println("\t\tgoroutineD sleep 5 minutes.")
time.Sleep( * time.Second)
// send a value down the responseChan
fmt.Println("\t\tgoroutineD send w22222222222.")
responseChan <- "w22222222222!" }
执行结果:
goroutineC create response chan.
goroutineD wait to get response chan.
goroutineD has gotten response chan.
goroutineD sleep 5 minutes.
goroutineC waiting to read.
goroutineD send wassup.
goroutineD sleep 5 minutes.
goroutineC get Response: wassup!
goroutineD send wassup.
goroutineC get Response: w22222222222!

参考:http://tleyden.github.io/blog/2013/11/23/understanding-chan-chans-in-go/

https://www.goin5minutes.com/blog/channel_over_channel/

Visual time lapse walkthrough

Keep in mind that Goroutine C is the “real consumer” even though it will be the one which writes to the request channel.

The request channel starts out empty.

Goroutine C passes a “response channel” to go routine D via the request channel

Goroutine C starts reading from the (still empty) response channel.

Goroutine D writes a string to the response channel

Goroutine C now is able to read a value from response channel, and get’s the “wassup!” message

And now we are back to where we started

golang go语言通道类型的通道示例 通道的通道的更多相关文章

  1. Go语言规格说明书 之 通道类型(Channel types)

    go version go1.11 windows/amd64 本文为阅读Go语言中文官网的规则说明书(https://golang.google.cn/ref/spec)而做的笔记,介绍Go语言的 ...

  2. Go语言-通道类型

    通道(Channel)是Go语言中一种非常独特的数据结构.它可用于在不同Goroutine之间传递类型化的数据,并且是并发安全的.相比之下,我们之前介绍的那些数据类型都不是并发安全的.这一点需要特别注 ...

  3. IBM WebSphere MQ 通道类型配置

    IBM WebSphere MQ 通道类型配置 初学MQ,四种常见通道,windows下操作 目录 Sender--Receiver Server-Receiver Server-Requester ...

  4. 学习Golang语言(6):类型--切片

    学习Golang语言(1): Hello World 学习Golang语言(2): 变量 学习Golang语言(3):类型--布尔型和数值类型 学习Golang语言(4):类型--字符串 学习Gola ...

  5. go语言从例子开始之Example22.协程之通道

    通道 是连接多个 Go 协程的管道.你可以从一个 Go 协程将值发送到通道,然后在别的 Go 协程中接收. Example: package main import "fmt" f ...

  6. [golang note] 内建类型

    基础类型 √ golang内建基础类型有布尔类型.整数类型.浮点类型.复数类型.字符串类型.字符类型和错误类型. 复合类型 √ golang支持的复合类型有指针.数组.数组切片.字典.通道.结构体和接 ...

  7. golang拾遗:自定义类型和方法集

    golang拾遗主要是用来记录一些遗忘了的.平时从没注意过的golang相关知识. 很久没更新了,我们先以一个谜题开头练练手: package main import ( "encoding ...

  8. 生成跨语言的类型声明和接口绑定的工具(Djinni )

    Djinni 是一个用来生成跨语言的类型声明和接口绑定的工具,主要用于 C++ 和 Java 以及 Objective-C 间的互通. 示例接口定义文件: # Multi-line comments ...

  9. 从Golang中open的实现方式看Golang的语言设计

    Golang有很多优点: 开发高效:(C语言写一个hash查找很麻烦,但是go很简单) 运行高效:(Python的hash查找好写,但比Python高效很多) 很少的系统库依赖:(环境依赖少,一般不依 ...

  10. C语言的类型大小

    C语言的类型大小 设计程序的时候我们一般会考虑的尽量的周全,尤其是像C这样的静态类型语言. 有一些溢出的问题就源于没有搞清楚变量的大小范围,所以我们编写的时候需要特别注意 C的整形(整数类型)大小 C ...

随机推荐

  1. fork分支与源分支同步代码

    最进软件工程课程要团队开发做个网站项目,于是我在团队里推了使用github这种网站来协同开发,但是出现了个问题:fork后的代码无法 与源分支代码同步,导致fork分支的代码只有自己写的那部分,而不是 ...

  2. 2 Servlet 细节

    1 Servlet 配置详解 ①  由于客户端在浏览器只能通过URL访问web服务器的资源,所以Servlet程序若想被外界访问,必须把Servlet 程序映射到一个URL 地址上,这个工作在项目we ...

  3. C# Note11:如何优雅地退出WPF应用程序

    前言 I should know how I am supposed to exit my application when the user clicks on the Exit menu item ...

  4. 将Vue移动端项目打包成手机app---HBuilder

    将移动端页面打包成app 1.使用 HBuilder 直接编译打包 点击左上角 文件>打开目录>选择目录  选择用Webpack打包好的dist文件目录 由于我添加到项目了,所以会显示该项 ...

  5. hive表链接

    等值连接 不等职链接 外部链接 没有包含在聚合函数(这里是count)中的列,都需要包含在group by函数中: 正确的外链接的写法,用的是右外链接: 自链接表 把同一张表 看成了2张表

  6. Redis事物

    redis事物定义: >Redis事务是一个单独的隔离操作:事务中的所有命令都会序列化.按顺序地执行.事务在执行的过程中,不会被其他客户端发送来的命令请求所打断. >Redis事务的主要作 ...

  7. yield send 的一些使用细节

    其实日常中我们使用最多的是 return 很少会使用到 yield 去创造一个生成器.一般就是算算算 算完之后用 return 返回一把. 但是有些情况下 比如需要节约内存不需要一把全部返回,每次使用 ...

  8. placeholder解决兼容各种IE浏览器的方法

    <input id="search" type="text" class="box" class="inputText&qu ...

  9. PyCharm的使用

    1.pycharm的下载和安装 首先,去jetbrains官网https://www.jetbrains.com/pycharm/download/#section=windows 中下载最新版的pr ...

  10. 创建简单的表单Demo

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...