Golang – Channel Unbuffered VS Buffered区别
参考文章:
- https://diiyw.com/2019/10/24/go-channel-buffer/
- https://blog.wu-boy.com/2020/01/when-to-use-go-channel-and-goroutine/
在Go中我们make一个channel有两种方式,分别是有缓冲的 (buffered) 和没缓冲的 (unbuffered)
- Buffered channel 创建方式为 make(chan TYPE,SIZE)
– 如:make(chan string,2) 就是创建一个string类型,buffer大小为3的channel - Unbuffered channel创建方式为 make(chan TYPE)
– 如: make(chan string) 就是创建一个string 类型的channel,无需定义buffer大小
Unbuffered 和 buffered channel的区别
- Unbuffered channel是channel发送和接收是同时发生的
– 如: ch := make(chan int) 如果没goroutine 读取接收者 <-ch 那么发送者 ch<- 就会一直塞着 - Buffered channel 只有列队满了才可能发生阻塞
【Unbuffered Channel的代码案例】
- 同步进行的,在读取channel会阻塞,直到goroutine当中发送数据到channel
func main() {
ch := make(chan int)
go func() {
ch <- 42 // 发送操作
fmt.Println("Sent value")
}()
value := <-ch // 接收操作
fmt.Println("Received value:", value)
}
- 以下是unbuffered channel,loop着接收来自channel的数据
- 由于是同步进行的,所以必须一进就一出,如果读取的部分慢了,那么写入的部分就会卡着等待了
func main() {
ch := make(chan int)
// 启动一个 goroutine 来发送数据
go func() {
for i := 0; i < 5; i++ { // 循环发送5次数据
ch <- i
fmt.Println("Sent value:", i)
time.Sleep(time.Second) // 睡眠1秒,模拟一些工作
}
close(ch) // 发送完成后关闭通道
}()
// 主 goroutine 接收数据
for value := range ch {
fmt.Println("Received value:", value)
}
}
【Buffered Channel的代码案例】
- 都是异步处理的,不会因为读取的数据慢了而阻塞
- 如果channel满了,就会阻塞,必须等待channel腾出空位了之后才能继续往内发送数据
func main() {
ch := make(chan int, 2) // 创建一个容量为 2 的缓冲通道
ch <- 1 // 发送操作,不会阻塞
fmt.Println("Sent value 1")
ch <- 2 // 发送操作,不会阻塞
fmt.Println("Sent value 2")
go func() {
ch <- 3 // 发送操作,此时会阻塞,直到有空位
fmt.Println("Sent value 3")
}()
value1 := <-ch // 接收操作
fmt.Println("Received value:", value1)
value2 := <-ch // 接收操作
fmt.Println("Received value:", value2)
value3 := <-ch // 接收操作,解除阻塞
fmt.Println("Received value:", value3)
}
输出结果:
Sent value 1
Sent value 2
Received value: 1
Received value: 2
Sent value 3
Received value: 3
Facebook评论