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 ...
随机推荐
- 1 Servlet 简介
1 Servlet是sun公司提供的一门用于开发动态web资源的技术.用户若用Java技术开发一个动态web资源或者网页,需要完成以下2个步骤:① 编写一个Java类,实现servlet接口② 把开发 ...
- 【Java基础】求出1-100之间偶数和
结果:
- CLOUD设置过滤方案不共享
1.打开BOS,找到应用框架-动态表单-过滤方案另存 2.找到共享给他人,把可见性全部去掉
- Redis事物
redis事物定义: >Redis事务是一个单独的隔离操作:事务中的所有命令都会序列化.按顺序地执行.事务在执行的过程中,不会被其他客户端发送来的命令请求所打断. >Redis事务的主要作 ...
- RocketMQ消息队列安装
一.官方安装文档 http://rocketmq.apache.org/docs/quick-start/ 下载地址 https://github.com/apache/rocketmq/releas ...
- table index & delete array item
table index & delete array item https://www.iviewui.com/components/table#ZDYLMB 编辑 row = { " ...
- python设计模式第二十五天【访问者模式】
1.应用场景 (1)将数据和行为进行分离,不同的角色具有不同的行为 2.代码实现
- jdbc 接口的用法 Statement和PreparedStatement的区别!
package cn.zhouzhou; import java.sql.Connection; import java.sql.DriverManager; import java.sql.Resu ...
- PLSQL 汉化
自动导入PLSQL安装目录: 一直下一步就可以了: 之后重新打开:
- Git拉取项目时报错“remote: HTTP Basic: Access denied”解决方法
问题: Git拉取项目时报错“remote: HTTP Basic: Access denied”,此问题多为本地密码与远端密码不符导致. 解决方法: 在下载地址中加上用户名和密码即可,如下: htt ...