几点注意: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. java线程池实现原理

    (1):线程池存在哪些状态,这些状态之间是如何进行切换的呢? (2):线程池的种类有哪些? (3):创建线程池需要哪些参数,这些参数的具体含义是什么? (4):将任务添加到线程池之后运行流程? (5) ...

  2. mysql5.7 的 user表的密码字段从 password 变成了 authentication_string

    来源: http://www.zhimengzhe.com/shujuku/other/267631.html 感觉还是挺坑的 自己没了解清楚 就动手 转帖一下 mark 一下. 1.首先停止正在运行 ...

  3. 网络编程--使用UDP发送接收数据

    package com.zhangxueliang.udp; import java.io.IOException; import java.net.DatagramPacket; import ja ...

  4. eclipse中添加tomcat

    https://blog.csdn.net/Forlogen/article/details/54090335(copy) 为了Java Web的开发,下面我们来安装一下Tomcat服务器,并将其配置 ...

  5. npm install、npm install --save、npm install --save --dev、npm install -S、npm install -D的区别

    npm install X: 会把X包安装到node_modules目录中 不会修改package.json 之后运行npm install命令时,不会自动安装X npm install X –sav ...

  6. python[练习题]:实现Base64编码

    要求自己实现算法,不用库. Base64简介: Base64是一种用64个字符来表示任意二进制数据的方法. 用记事本打开exe.jpg.pdf这些文件时,我们都会看到一大堆乱码,因为二进制文件包含很多 ...

  7. Spark开发第一个程序

    simon@simon-Lenovo-G400:~/.ssh$ touch authorized_keyssimon@simon-Lenovo-G400:~/.ssh$ cat id_rsa.pub ...

  8. TensorFlow总结

    第一 基础 1. 定义变量 #定义维度为[2,3], 平均值为·1, 标准差为1,类型为float32,名称为w1的服从正态分布的变量 w1 = tf.Variable(tf.random_norma ...

  9. ECS配置lamp环境

    1.安装apache 1.1 安装apache [root@nmserver-7 ~]# yum install httpd httpd-devel 1.2 启动apache服务 [root@nmse ...

  10. How to enable usb on vbox

    Device-->Install Guest Addition Shared Folders Settings-->Advanced-->Shared Clipboard--> ...