Golang Channel范围循环
在使用Golang的channel进行范围循环时遇到了问题。代码如下:
ch := make(chan int)
go func() {
for i := 0; i < 5; i++ {
ch <- i
}
close(ch)
}()
for v := range ch {
fmt.Println(v)
}
为什么必须在goroutine中显式调用close(ch),否则程序会报死锁错误?如果发送端不关闭channel,有什么办法可以让接收端安全地退出循环而不导致死锁?
2 回复
Golang中,使用for range循环遍历channel会持续接收数据,直到channel被关闭。若未关闭channel,会导致死锁。示例:
ch := make(chan int)
go func() {
for i := 0; i < 3; i++ {
ch <- i
}
close(ch)
}()
for v := range ch {
fmt.Println(v)
}
更多关于Golang Channel范围循环的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
在Go语言中,使用range关键字可以方便地遍历(循环)channel中的元素,直到channel被关闭。这是一种常见的并发模式,用于从channel中持续接收数据。
语法
for value := range ch {
// 处理value
}
ch:要遍历的channel。value:每次从channel接收到的值。- 循环会持续从channel接收数据,直到channel被关闭(close(ch)),然后自动退出。
示例代码
package main
import (
"fmt"
"time"
)
func main() {
ch := make(chan int)
// 启动一个goroutine向channel发送数据
go func() {
for i := 1; i <= 5; i++ {
ch <- i
time.Sleep(500 * time.Millisecond) // 模拟处理延迟
}
close(ch) // 发送完成后关闭channel
}()
// 使用range循环接收数据
for num := range ch {
fmt.Println("Received:", num)
}
fmt.Println("Channel closed, loop exited.")
}
关键点
- 必须关闭channel:如果发送方不关闭channel,
range循环会一直阻塞等待,导致goroutine泄漏或死锁。 - 适用于缓冲和非缓冲channel:两种类型都支持
range循环。 - 单向channel:只能对可读channel(
<-chan T)使用range循环。
注意事项
- 确保在适当的时候关闭channel,避免资源泄漏。
- 如果多个goroutine向同一个channel发送数据,需协调关闭时机(例如使用
sync.WaitGroup)。
这是一种高效、简洁的并发数据接收方式。

