Golang中的Channel详解(一):定义与基本操作

开发 前端
Channel是一个协程安全的管道,一端写入数据,一端读取数据,写入和读取都是原子操作,有点类似于消息队列,只不过channel是内存级别的。在channel出现之前,需要手动管理共享内存,这样会带来一定的复杂度和不可知的问题。

Golang中的channel是不同goroutines之间进行通信和同步的桥梁,借助channel,可以很方便写多协程通信程序。

如何理解channel

Channel是一个协程安全的管道,一端写入数据,一端读取数据,写入和读取都是原子操作,有点类似于消息队列,只不过channel是内存级别的。在channel出现之前,需要手动管理共享内存,这样会带来一定的复杂度和不可知的问题。而channel提供了一种更简单、更安全的方式来进行并发编程,借助channel,可以在不共享内存的情况下实现多个goroutine之间的通信。

channel的基本操作

使用make()函数来创建一个channel示例,并且需要指定channel中元素的类型和容量(可选),例如:

ch := make(chan int)  // 创建一个int类型的channel

这条创建语句没有指定容量,就是创建了一个无缓冲的channel,如果一个goroutine往这个channel发送数据,那么这个oroutine就会被阻塞住,直到有其它goroutine读取了channel 的数据才能继续运行。创建channel时如果指定了容量,就是有缓冲的channel,例如:

ch := make(chan int, 10) // 创建一个容量为10的int类型的channel

对于有缓冲的channel来说,只要当前channel里的元素总数不大于这个指定的容量,当前的goroutine就不会被阻塞住。

往channel写数据使用<-操作符,例如:

ch := make(chan int)
 ch <- 1 //将值1发送到通道中

从channel读取数据也是使用<-操作符,例如:

val := <- ch //从通道中接收上一个发送的值

当不再使用channel时,使用close()方法关闭channel,例如:

close(ch)

当channel关闭后,如果继续往里面写数据,则会panic;如果继续读的话,不会产生panic,如果还有数据的话也可以读到数据,如果没有数据的话将得到零值(对应类型的默认值)。判断当前channel是否被关闭,可以使用下面的写法:

if v, ok := <-ch; !ok {
   fmt.Println("channel已关闭并且数据已被读完")
 }

也可以使用for range的方式,读取完数据后循环也随着结束,例如:

for v := range ch {
  // ...
}
责任编辑:姜华 来源: 今日头条
相关推荐

2023-05-29 09:25:38

GolangSelect

2023-06-27 08:45:19

原子操作Golang

2023-10-31 09:10:39

2023-03-30 07:52:03

Golang接口

2021-09-06 13:15:16

golang chan技巧语言

2023-05-17 08:42:46

深拷贝Golang

2023-08-08 14:51:29

2023-08-02 09:07:27

Golangio 包

2021-06-18 06:31:55

PyTorchPython深度学习

2021-11-18 09:20:29

Channel语言代码

2023-06-02 08:29:24

https://wwMutex

2021-09-22 12:56:19

编程技能Golang

2023-08-03 08:48:07

Golang接口

2023-11-27 15:02:37

BytesGolang

2023-10-23 12:35:36

Golang追加操作

2023-08-31 09:28:12

Golang可导出函数

2021-07-02 06:54:45

GoJavachannel

2023-06-26 08:28:35

Sync.CondGolang

2023-06-05 09:23:00

Golang同步工具

2023-06-09 08:16:09

GolangStruct Tag
点赞
收藏

51CTO技术栈公众号