【发布时间】:2023-03-17 02:05:01
【问题描述】:
我想和你比较两个类似的案例——唯一的区别是处理值生成的方式
- 第一种情况:选择一种情况下的值生成
package main
import (
"fmt"
"math/rand"
"time"
)
func main() {
generateValues := func(done <-chan interface{}) <-chan int {
values := make(chan int)
go func() {
defer fmt.Println("All values generated")
defer close(values)
for {
select {
case <-done:
fmt.Println("DONE")
return
case values <- rand.Int():
fmt.Println("Generated")
}
}
}()
return values
}
done := make(chan interface{})
values := generateValues(done)
for i := 0; i < 3; i++ {
fmt.Printf("Received value: %v\n", <-values)
}
fmt.Println("Closing the channel")
close(done)
time.Sleep(5 * time.Second)
}
去游乐场:https://go.dev/play/p/edlOSqdZ9ys
- 第二种情况:默认情况下的值生成
package main
import (
"fmt"
"math/rand"
"time"
)
func main() {
generateValues := func(done <-chan interface{}) <-chan int {
values := make(chan int)
go func() {
defer fmt.Println("All values generated")
defer close(values)
for {
select {
case <-done:
fmt.Println("DONE")
return
default:
values <- rand.Int()
fmt.Println("Generated")
}
}
}()
return values
}
done := make(chan interface{})
values := generateValues(done)
for i := 0; i < 3; i++ {
fmt.Printf("Received value: %v\n", <-values)
}
fmt.Println("Closing the channel")
close(done)
time.Sleep(5 * time.Second)
}
去游乐场:https://go.dev/play/p/edlOSqdZ9ys
如您所见,第二种情况似乎导致未打印“完成”并且未调用与“延迟”相关的调用的情况。我相信我们这里有 goroutine 泄漏,但无法清楚地解释它。我期待与第一种情况相同的行为。
有人可以帮助理解它们之间的区别吗?
【问题讨论】:
标签: go select default channel goroutine