一、什么是 Channel
Channel 是 Go 语言中一种核心的并发原语,用于在不同的 goroutine 之间进行通信和同步。它提供了一种机制,允许一个 goroutine 向另一个 goroutine 发送数据,实现了"不要通过共享内存来通信,而应该通过通信来共享内存"的并发哲学。
二、Channel 的基本操作
1、创建 Channel
// 无缓冲 channel
ch := make(chan int)
// 有缓冲 channel,容量为 10
ch := make(chan int, 10)
2、发送和接收数据
// 发送数据
ch <- value
// 接收数据
value := <-ch
// 接收数据并检查 channel 是否关闭
value, ok := <-ch
if !ok {
// channel 已关闭
}
3、关闭 Channel
close(ch)
三、Channel 的类型
1. 无缓冲 Channel (Unbuffered Channel)
无缓冲 channel 的容量为 0,发送和接收操作会阻塞,直到另一端准备好。
func unbufferedChannelDemo() {
ch := make(chan int) // 无缓冲 channel
go func() {
fmt.Println("Goroutine 发送数据")
ch <- 42 // 发送数据,会阻塞直到主 goroutine 接收
fmt.Println("Goroutine 发送完成")
}()
time.Sleep(1 * time.Second) // 给 goroutine 时间启动
fmt.Println("主 goroutine 准备接收数据")
value := <-ch // 接收数据
fmt.Printf("接收到数据: %d\n", value)
time.Sleep(100 * time.Millisecond) // 确保 goroutine 完成
}
打印结果:
Goroutine 发送数据
//主goroutine睡眠1秒,确保子goroutine有足够时间启动并执行到发送操作(即阻塞在发送语句)。主 goroutine 准备接收数据
接收到数据: 42
Goroutine 发送完成
//主goroutine睡眠100毫秒,以确保子goroutine完成打印(但输出已经完成)
2. 有缓冲 Channel (Buffered Channel)
有缓冲 channel 有一个固定大小的缓冲区,只有当缓冲区满时发送操作才会阻塞,只有当缓冲区空时接收操作才会阻塞。
func bufferedChannelDemo() {
ch := make(chan int, 3) // 容量为 3 的有缓冲 channel
// 发送数据,不会立即阻塞
ch <- 1
ch <- 2
ch <- 3
fmt.Println("已发送 3 个数据")
// 再发送一个数据会阻塞,因为缓冲区已满
go func() {
ch <- 4 // 这会阻塞,直到有空间可用
fmt.Println("第 4 个数据已发送")
}()
time.Sleep(1 * time.Second) // 给 goroutine 时间启动
// 接收数据,释放缓冲区空间
fmt.Println("接收数据:", <-ch)
fmt.Println("接收数据:", <-ch)
tim

最低0.47元/天 解锁文章
1万+

被折叠的 条评论
为什么被折叠?



