Golang 中的 channel 有两种类型,分别为:无缓冲 channel 和 带缓冲 channel。
无缓冲的通道是指在接收前没有能力保存任何值的通道。这种类型的通道要求发送 goroutine 和接收 goroutine 同时准备好,才能完成发送和接收操作。
如果两个 goroutine 没有同时准备好,通道会导致先执行发送或接收操作的 goroutine 阻塞等待。
c1:= make(chan TYPE)
参数 | 描述 |
---|---|
c1 | channel 变量名。 |
chan | 创建 channel 使用的关键字。 |
TYPE | channel 的类型。 |
我们创建了一个无缓冲的 channel c1,其类型为 chan TYPE。
使用无缓冲 channel 读写数据
package main
import (
"fmt"
"time"
)
//使用无缓冲 channel 发送数据
func writeRoutine(intChan chan int) {
for i := 0; i < 3; i++ {
intChan <- i
time.Sleep(time.Duration(2) * time.Second)
fmt.Println("Send", i)
}
//关闭 channel
close(intChan)
}
// 从无缓冲 channel 读取数据
func readRoutine(intChan chan int) {
for val := range intChan{
fmt.Println("Receive =", val)
time.Sleep(time.Duration(10) * time.Second)
}
return
}
func main() {
fmt.Println("嗨客网(www.haicoder.net)")
// 创建无缓冲 channel
c := make(chan int)
go writeRoutine(c)
readRoutine(c)
}
程序运行后,控制台输出如下:
首先,我们使用 make 创建了一个无缓冲的 channel,接着,分别创建了一个负责写入数据的协程 writeRoutine 和一个负责读取数据的协程 readRoutine。
在 writeRoutine 协程里,我们使用 for 循环 发送三次数据,每次发送数据后,都使用 sleep 等待两秒,数据全部发送完毕,使用 close 关闭 channel。
在 readRoutine 函数里,使用 for range 接受数据,每次接受完数据后,都等待 10 秒钟。接受数据的时长明显长于发送数据的时长。
从运行结果来看,每次发送完数据,必须要等到接受到数据之后,才会继续下一次数据的发送,因此,发送数据的 channel 数据发送完毕之后,接受的 channel 没有读取该数据,那么此时该 channel 是阻塞的,必须要等到接受完数据之后,才可以继续发送下一次数据。这就是无缓冲 channel 的特点。
无缓冲的通道是指在接收前没有能力保存任何值的通道。这种类型的通道要求发送 goroutine 和接收 goroutine 同时准备好,才能完成发送和接收操作。
如果两个 goroutine 没有同时准备好,通道会导致先执行发送或接收操作的 goroutine 阻塞等待。Go 语言无缓冲 channel 创建:
c1 := make(chan int)