golang go语言通道类型的通道示例 通道的通道
几点注意: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语言通道类型的通道示例 通道的通道的更多相关文章
- Go语言规格说明书 之 通道类型(Channel types)
go version go1.11 windows/amd64 本文为阅读Go语言中文官网的规则说明书(https://golang.google.cn/ref/spec)而做的笔记,介绍Go语言的 ...
- Go语言-通道类型
通道(Channel)是Go语言中一种非常独特的数据结构.它可用于在不同Goroutine之间传递类型化的数据,并且是并发安全的.相比之下,我们之前介绍的那些数据类型都不是并发安全的.这一点需要特别注 ...
- IBM WebSphere MQ 通道类型配置
IBM WebSphere MQ 通道类型配置 初学MQ,四种常见通道,windows下操作 目录 Sender--Receiver Server-Receiver Server-Requester ...
- 学习Golang语言(6):类型--切片
学习Golang语言(1): Hello World 学习Golang语言(2): 变量 学习Golang语言(3):类型--布尔型和数值类型 学习Golang语言(4):类型--字符串 学习Gola ...
- go语言从例子开始之Example22.协程之通道
通道 是连接多个 Go 协程的管道.你可以从一个 Go 协程将值发送到通道,然后在别的 Go 协程中接收. Example: package main import "fmt" f ...
- [golang note] 内建类型
基础类型 √ golang内建基础类型有布尔类型.整数类型.浮点类型.复数类型.字符串类型.字符类型和错误类型. 复合类型 √ golang支持的复合类型有指针.数组.数组切片.字典.通道.结构体和接 ...
- golang拾遗:自定义类型和方法集
golang拾遗主要是用来记录一些遗忘了的.平时从没注意过的golang相关知识. 很久没更新了,我们先以一个谜题开头练练手: package main import ( "encoding ...
- 生成跨语言的类型声明和接口绑定的工具(Djinni )
Djinni 是一个用来生成跨语言的类型声明和接口绑定的工具,主要用于 C++ 和 Java 以及 Objective-C 间的互通. 示例接口定义文件: # Multi-line comments ...
- 从Golang中open的实现方式看Golang的语言设计
Golang有很多优点: 开发高效:(C语言写一个hash查找很麻烦,但是go很简单) 运行高效:(Python的hash查找好写,但比Python高效很多) 很少的系统库依赖:(环境依赖少,一般不依 ...
- C语言的类型大小
C语言的类型大小 设计程序的时候我们一般会考虑的尽量的周全,尤其是像C这样的静态类型语言. 有一些溢出的问题就源于没有搞清楚变量的大小范围,所以我们编写的时候需要特别注意 C的整形(整数类型)大小 C ...
随机推荐
- [转帖]Docker容器CPU、memory资源限制
Docker容器CPU.memory资源限制 https://www.cnblogs.com/zhuochong/p/9728383.html 处理事项内容等 这一块内容感觉 不清楚.. 背景 在使用 ...
- 爱上linux 简单实现移动办公处理环境.
1. 这周一直在鼓捣linux上面的环境测试. 简单的将 我们的产品部署到了linux上面 详情见前面的 blog 2. 有时候下班了 或者是 在WC (科技园wc排队 说多了都是泪) 或者是眼睛不舒 ...
- Oracle pivot行转列函数案例
with temp as( select '湖北省' province,'武汉市' city,'第一' ranking from dual union all select '湖北省' provinc ...
- js的日期操作:String转date日期格式、求日期差
一.在js中String类型转成date格式 var date = new Date("2018-9-21 14:58:43");//就是这么简单 二.date转String类型就 ...
- day 7-6 GIL,死锁,递归锁与信号量,Event,queue,
摘要: 1.死锁与递归锁 2.信号量 3.Event 4.Timer 5.GIL 6.Queue 7.什么时候该用多线程和多进程 一. 死锁与递归锁 所谓死锁: 是指两个或两个以上的进程或线程在执行过 ...
- Day 4-8 hashlib加密模块
HASH Hash,一般翻译做“散列”,也有直接音译为”哈希”的,就是把任意长度的输入(又叫做预映射,pre-image),通过散列算法,变换成固定长度的输出,该输出就是散列值.这种转换是一种压缩映射 ...
- python中random模块
random与numpy.random对比: 1.random.random():生成[0,1)之间的随机浮点数: numpy.random.random():生成[0,1)之间的随机浮点数: num ...
- TField OnValidate 事件
Occurs just before the data is written to the record buffer. Write an OnValidate event handler to va ...
- How to mount HFS EFI on macOS
mount_hfs /dev/disk0s1 /volumes/efi
- Ontology
本体网络(Ontology) 新一代分布式信任链网 在开始了解项目之前,让我们先看一段“第一财经”频道关于“本体网络”的介绍: 项目介绍 1摘要 类型 提供不同分布式应用场景的开放基础模块,构建跨链 ...