面试题答案
一键面试- 关闭channel的策略:
- 当所有发送数据的goroutine都完成数据发送后,关闭channel。为了确保所有发送goroutine都完成,可以使用
sync.WaitGroup
来等待所有发送goroutine结束。 - 主goroutine通过
select
语句的case
来接收数据,并通过ok
值判断channel是否关闭。当ok
为false
时,说明channel已关闭,此时主goroutine可以安全退出接收循环。
- 当所有发送数据的goroutine都完成数据发送后,关闭channel。为了确保所有发送goroutine都完成,可以使用
- 代码示例:
package main
import (
"fmt"
"sync"
)
func main() {
var wg sync.WaitGroup
ch := make(chan int)
// 模拟多个发送数据的goroutine
numSenders := 3
for i := 0; i < numSenders; i++ {
wg.Add(1)
go func(id int) {
defer wg.Done()
for j := id * 10; j < (id+1)*10; j++ {
ch <- j
}
}(i)
}
go func() {
wg.Wait()
close(ch)
}()
// 主goroutine接收数据
for {
select {
case val, ok := <-ch:
if!ok {
fmt.Println("Channel is closed, exiting receive loop")
return
}
fmt.Println("Received:", val)
}
}
}
在上述代码中:
- 首先创建了一个
WaitGroup
和一个channel。 - 启动多个goroutine向channel发送数据,每个goroutine使用
wg.Add(1)
和wg.Done()
来标记开始和结束。 - 一个匿名goroutine使用
wg.Wait()
等待所有发送goroutine完成,然后关闭channel。 - 主goroutine通过
select
语句接收数据,当ok
为false
时退出接收循环,确保不会丢失数据或发生死锁。