package main
import (
"fmt"
)
func main() {
ch := make(chan int)
// 模拟多个写入goroutine
for i := 0; i < 3; i++ {
go func(id int) {
for j := 0; j < 3; j++ {
ch <- id*3 + j
}
close(ch) // 每个写入goroutine完成工作后关闭通道
}(i)
}
// 主goroutine读取通道数据
for {
data, ok := <-ch
if!ok {
// 通道关闭且数据读完
break
}
fmt.Println("Received:", data)
}
fmt.Println("All data processed.")
}
原理解释
- 通道创建:
ch := make(chan int)
创建一个整数类型的通道 ch
,用于在多个 goroutine 之间传递数据。
- 写入 goroutine:通过
for i := 0; i < 3; i++
启动了3个写入 goroutine,每个 goroutine 向通道 ch
中写入3个数据,并且在完成写入后调用 close(ch)
关闭通道。注意,在实际应用中如果多个 goroutine 都尝试关闭同一个通道会导致运行时恐慌,这里由于每个 goroutine 是独立的逻辑块,在各自完成任务后关闭通道不会引发该问题。
- 主 goroutine 读取:主 goroutine 通过
for { data, ok := <-ch }
这种形式从通道中读取数据。ok
表示通道是否关闭且没有数据可读。当 ok
为 false
时,说明通道已关闭且数据已读完,此时通过 break
跳出循环,完成数据的安全读取和处理,避免了关闭读取异常。