- 0
- 0
- 约5.41千字
- 约 11页
- 2025-06-24 发布于四川
- 举报
第
Go语言?Channel通道详解
目录一、通道介绍1、声明通道2、创建通道二、channel操作1、发送2、接收3、关闭三、无缓冲通道四、有缓冲的通道1、有缓冲通道声明2、阻塞条件五、循环读取信道六、关闭通道七、单向通道总结
一、通道介绍
单纯地将函数并发执行是没有意义的。函数与函数间需要交换数据才能体现并发执行函数的意义。
虽然可以使用共享内存进行数据交换,但是共享内存在不同的goroutine中容易发生竞态问题。为了保证数据交换的正确性,必须使用互斥量对内存进行加锁,这种做法势必造成性能问题。
go提倡使用通信的方法代替共享内存,这里通信的方法就是使用通道(channel),如下图所示。
在地铁站、食堂、洗手间等公共场所人很多的情况下,大家养成了排队的习惯,目的也是避免拥挤、插队导致的低效的资源使用和交换过程。代码与数据也是如此,多个goroutine为了争抢数据,势必造成执行的低效率,使用队列的方式是最高效的,channel就是一种队列一样的结构。
Go语言中的通道(channel)是一种特殊的类型。在任何时候,同时只能有一个goroutine访问通道进行发送和获取数据。goroutine间通过通道就可以通信。
通道像一个传送带或者队列,总是遵循先入先出(FirstInFirstOut)的规则,保证收发数据的顺序。
1、声明通道
var变量chan元素类型
varch1chanint//声明一个传递整型的通道
varch2chanbool//声明一个传递布尔型的通道
varch3chan[]int//声明一个传递int切片的通道
chan类型的空值是nil,声明后需要配合make后才能使用。
所以通道只能传输一种类型的数据,比如chanint或者chanstring,所有的类型都可以用于通道,空接口interface{}也可以。甚至可以(有时非常有用)创建通道的通道。
2、创建通道
通道是引用类型,需要使用make进行创建(分配内存),格式如下:
varch1chanstring
ch1=make(chanstring)
//或者使用短类型
ch1:=make(chanstring)
示例
ch1:=make(chanint)//创建一个整型类型的通道
ch2:=make(chaninterface{})//创建一个空接口类型的通道,可以存放任意格式
typeEquipstruct{/*一些字段*/}
ch2:=make(chan*Equip)//创建Equip指针类型的通道,可以存放*Equip
二、channel操作
通道有发送(send)、接收(receive)和关闭(close)三种操作。发送和接收都使用-符号。
通道创建后,就可以使用通道进行发送和接收操作。
定义一个通道:
ch:=make(chanint)
1、发送
将一个值发送到通道中。
ch-10//把10发送到ch中
2、接收
从一个通道中接收值。
x:=-ch//从ch中接收值并赋值给变量x
-ch//从ch中接收值,忽略结果
3、关闭
我们通过调用内置的close函数来关闭通道
close(ch)
关于关闭通道需要注意的事情是,只有在通知接收方goroutine所有的数据都发送完毕的时候才需要关闭通道
通道是可以被垃圾回收机制回收的,它和关闭文件是不一样的,在结束操作之后关闭文件是必须要做的,但关闭通道不是必须的。
关闭后的通道有以下特点:
对一个关闭的通道再发送值就会导致panic。对一个关闭的通道进行接收会一直获取值直到通道为空。(如果通道中还有数据的话)对一个关闭的并且没有值的通道执行接收操作会得到对应类型的零值。关闭一个已经关闭的通道会导致panic。
三、无缓冲通道
无缓冲的通道又称为阻塞的通道
funcmain(){
ch:=make(chanint)
ch-10
fmt.Println(发送成功)
//这段代码仅作为描述无缓冲通道,实际会形成deadlock
//具体原因,看下述分析
上面这段代码能够通过编译,但是执行的时候会出现以下错误:
fatalerror:allgoroutinesareasleep-deadlock!
goroutine1
原创力文档

文档评论(0)