Loading [MathJax]/jax/input/TeX/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >go语言学习(五):通道的用法

go语言学习(五):通道的用法

作者头像
jinjunzhu
发布于 2020-08-20 02:02:59
发布于 2020-08-20 02:02:59
41900
代码可运行
举报
文章被收录于专栏:个人开发个人开发
运行总次数:0
代码可运行

go语言的作者Rob Pike认为,不要通过共享内存来实现通信,而应该通过通信来共享内存。多个goroutine之间可以通过通道来传递数据。通道是并发安全的,类似于一个FIFO的队列。go语言的通道定义需要使用make语句,如下,定义了一个存放3个int类型元素通道并向通道中输入了3个元素。同时用for循环取出。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
func main() {  ch1 := make(chan int, 3)  ch1 <- 2  ch1 <- 1  ch1 <- 3  close(ch1)  for elem1 := range ch1 {    fmt.Printf("The first element received from channel ch1: %v\n", elem1)  }}

上面的代码会在循环中不断从通道中取出元素,即使通道已经关闭了也会取出剩下的元素。如果通道没有关闭并且取完了通道中的元素,循环就会阻塞。

注意:

1)通道发送完数据后应该关闭。

2)发送操作和接受操作都会阻塞通道。

3)如果不指定通道的容量,那通道容量默认是0,称作非缓存通道;如果指定通道ro容量,如上面示例,称作缓存通道。

4)如果缓存通道容量满了,发送操作就会阻塞,直到接收通道接收了元素;如果通道空了,接收操作就会阻塞,直到有元素写入通道。如果是非缓存通道,则发送操作和接收操作都在执行时才不会被阻塞。这就说明缓存通道是一个异步操作,而非缓存通道是一个同步操作。

5)以下几种情况会跑出panic。

a.关闭一个已经关闭的通道

b.向关闭的通道发送或接收数据

c.通道没有初始化,而是一个nil

我们把接收操作赋值给2个参数,第二个参数就能判断通道是否已经关闭。比如用for循环接收通道中的元素,代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
for {    elem, ok := <-ch1    if !ok {      fmt.Printf("Receiver: close channel\n")      break    }    fmt.Printf("Receiver: received an element:%v\n", elem)  }

在我们开发过程中,有时候为了在方法参数中定义一个通道来收发数据,会定义一个单向通道,如下面代码,第一个通道只能发,第二个通道只能收

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
var sendChan = make(chan<- int, 1)var receiveChan1 = make(<- chan int, 1)
代码语言:javascript
代码运行次数:0
运行
复制

还可以定义返回值是单向通道的函数,如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
func getIntChan() <- chan int{}func getIntChan1()  chan <- int{}
代码语言:javascript
代码运行次数:0
运行
复制

go语言为通道提供了select语句配合使用,类似于java中的switch,也有一个默认的分支,示例如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
func main() {  // 准备好几个通道。  intChannels := [3]chan int{    make(chan int, 1),    make(chan int, 1),    make(chan int, 1),  }  // 随机选择一个通道,并向它发送元素值。  index := rand.Intn(3)  fmt.Printf("The index: %d\n", index)  intChannels[index] <- index  // 哪一个通道中有可取的元素值,哪个对应的分支就会被执行。  select {  case <-intChannels[0]:    fmt.Println("The first candidate case is selected.")  case <-intChannels[1]:    fmt.Println("The second candidate case is selected.")  case elem := <-intChannels[2]:    fmt.Printf("The third candidate case is selected, the element is %d.\n", elem)  default:    fmt.Println("No candidate case is selected!")  }}
代码语言:javascript
代码运行次数:0
运行
复制

注意:在for循环中使用select,如果要屏蔽某个case分支,可以将通道赋值为nil

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-04-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 jinjunzhu 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Java程序员学习Go指南(一)
转载:https://www.luozhiyun.com/archives/206
luozhiyun
2020/02/18
7800
Java程序员学习Go指南(一)
Go语言核心36讲(Go语言进阶技术五)--学习笔记
首先来说说单向通道。我们在说“通道”的时候指的都是双向通道,即:既可以发也可以收的通道。
郑子铭
2021/10/22
3560
Go语言核心36讲(Go语言进阶技术五)--学习笔记
Go语言核心36讲(Go语言进阶技术四)--学习笔记
作为 Go 语言最有特色的数据类型,通道(channel)完全可以与 goroutine(也可称为 go 程)并驾齐驱,共同代表 Go 语言独有的并发编程模式和编程哲学。
郑子铭
2021/10/21
3350
Go语言核心36讲(Go语言进阶技术四)--学习笔记
深入浅出Go语言通道chan类型
通道(chan)类似于一个队列,特性就是先进先出,多用于goruntine之间的通信
闫同学
2023/10/14
2220
Go语言学习(十一)| 通道
通道类型的值本身就是并发安全的,这也是 Go 语言自带的、唯一一个可以满足并发安全性的类型。
Mervyn
2020/07/21
2990
《郝林 :Go语言第一课》学习笔记
本文是慕课网上郝林的《Go语言第一课》的学习笔记。作为一名老码农,最近才下定决心来学习新的语言,有点惭愧,也有点兴奋。 本文是课程的学习笔记,重点把GO基本语法学习中的精要点做了下总结,也是给郝林老师的一个汇报。 学习GO语言,欢迎从郝林的《Go语言第一课》开始。
辉哥
2019/03/20
7630
《郝林 :Go语言第一课》学习笔记
7.Go编程快速入门学习
描述: 反射是指在程序运行期对程序本身进行访问和修改的能力。即支持反射的语言可以在程序编译期将变量的反射信息,如字段名称、类型信息、结构体信息等整合到可执行文件中,并给程序提供接口访问反射信息,这样就可以在程序运行期获取类型的反射信息,并且有能力修改它们。
全栈工程师修炼指南
2022/09/29
7270
Go通道机制与应用详解
Go语言(也称为Golang)是一个开源的编程语言,旨在构建简洁、高效和可靠的软件。其中,通道(Channel)是Go并发模型的核心概念之一,设计目的是为了解决不同协程(Goroutine)间的数据通信和同步问题。通道作为一个先进先出(FIFO)的队列,提供了一种强类型、线程安全的数据传输机制。
程序猿川子
2025/05/08
350
Go通道机制与应用详解
go语言学习-并发编程
1.After函数:起到定时器的作用,指定的纳秒后会向返回的channel中放入一个当前时间(time.Time)的实例。
solate
2019/07/22
6340
Go语言之goroutine和通道
在Go里,每一个并发执行的活动称为goroutine。 如果你是一名Java程序员,可以把goroutine比作为线程,但是goroutine和线程在数量上有很大的差别,原因在于Go语言引入了协程的概念,协程相比于线程是一种用户态的线程,协程更加轻量,实用更加经济,因此同样的服务器可以开销的协程数量要比线程多很多。
用户9282069
2021/12/13
6710
Golang 基础之基础语法梳理 (二)
单纯地将函数并发执行是没有意义的。函数与函数间需要交换数据才能体现并发执行函数的意义,channel就是它们之间的连接。
帽儿山的枪手
2022/03/20
7070
Golang 基础之基础语法梳理 (二)
Golang之旅23-通道channel
在goroutine并发执行的时候,需要在函数和函数之间进行通信。Go语言并发模式CSP(communicating Sequents Processes),通过通信共享内存。
皮大大
2021/03/02
3540
由浅入深聊聊Golang中select的实现机制
select是go语言中常用的一个关键字,其用法也一直被用作面试题来考核应聘者。今天,结合代码来分析下select的主要用法。
会呼吸的Coder
2020/02/17
1.5K0
Go语言学习笔记——常用关键字
for...range完成数据迭代,支持字符串、数组、数组指针、切片、字典、通道类型,返回索引、键值数据。
windealli
2024/04/15
1360
Go语言学习笔记——常用关键字
channel
单纯地将函数并发执行是没有意义的。函数与函数间需要交换数据才能体现并发执行函数的意义。
Michel_Rolle
2023/11/30
2.7K0
Go语言学习笔记——常用关键字
for...range完成数据迭代,支持字符串、数组、数组指针、切片、字典、通道类型,返回索引、键值数据。
windealli
2024/04/10
1320
Go语言学习笔记——常用关键字
《Go 语言程序设计》读书笔记 (五) 协程与通道
以最简单方式调用make函数创建的是一个无缓冲的channel,但是我们也可以指定第二个整形参数,对应channel的容量。如果channel的容量大于零,那么该channel就是带缓冲的channel。
KevinYan
2020/01/14
5010
《Go 语言程序设计》读书笔记 (五) 协程与通道
go-并发
Go语言的并发通过 goroutine 实现。 goroutine 类似于线程,属于用户态的线程,我们可以根据需要创建成千上万个 goroutine 并发工作。 goroutine 是由Go语言的运行时(runtine)调度完成,而线程是由操作系统调度完成的。
新人小试
2020/03/27
7150
go-并发
《快学 Go 语言》第 12 课 —— 神秘的地下通道
不同的并行协程之间交流的方式有两种,一种是通过共享变量,另一种是通过队列。Go 语言鼓励使用队列的形式来交流,它单独为协程之间的队列数据交流定制了特殊的语法 —— 通道。
老钱
2018/12/24
4180
《快学 Go 语言》第 12 课 —— 神秘的地下通道
GoLang协程与通道---中
通道可以被显式的关闭;尽管它们和文件不同:不必每次都关闭。只有在当需要告诉接收者不会再提供新的值的时候,才需要关闭通道。只有发送者需要关闭通道,接收者永远不会需要。
大忽悠爱学习
2022/08/23
8670
相关推荐
Java程序员学习Go指南(一)
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验