goroutines 垃圾是否与其通道一起收集?
Are goroutines garbage collected together with their channels?
想象一下下面的代码:
func waitForOneOfTwoProcesses() {
c := make(chan bool)
go func() {
time.Sleep(1 * time.Second)
c<-true
}()
go func() {
time.Sleep(2 * time.Second)
c<-true
}()
<-c
}
这是否泄漏了通道和 goroutine,或者 Go 是否认识到 c
已经消失并且 goroutine 可以退出?
如果通道的缓冲区大小为 2,答案会有什么不同吗?
如果通道是无缓冲的,那么其中一个匿名函数将不会 return。该程序泄漏了一个 goroutine 和通道。
如果通道的缓冲区大小大于或等于 1,则两个匿名函数都将 return。 goroutines 和 channel 使用的资源将被回收。
大小为 1 的缓冲区足以防止泄漏。函数 waitForOneOfTwoProcesses
接收发送到 c
的值之一。发送到c
的第二个值缓存在通道中(由GC收集)。
另一种确保 goroutines return 的方法是使用非阻塞发送。将 c <- true
行替换为:
select {
case c <- true:
default:
}
想象一下下面的代码:
func waitForOneOfTwoProcesses() {
c := make(chan bool)
go func() {
time.Sleep(1 * time.Second)
c<-true
}()
go func() {
time.Sleep(2 * time.Second)
c<-true
}()
<-c
}
这是否泄漏了通道和 goroutine,或者 Go 是否认识到 c
已经消失并且 goroutine 可以退出?
如果通道的缓冲区大小为 2,答案会有什么不同吗?
如果通道是无缓冲的,那么其中一个匿名函数将不会 return。该程序泄漏了一个 goroutine 和通道。
如果通道的缓冲区大小大于或等于 1,则两个匿名函数都将 return。 goroutines 和 channel 使用的资源将被回收。
大小为 1 的缓冲区足以防止泄漏。函数 waitForOneOfTwoProcesses
接收发送到 c
的值之一。发送到c
的第二个值缓存在通道中(由GC收集)。
另一种确保 goroutines return 的方法是使用非阻塞发送。将 c <- true
行替换为:
select {
case c <- true:
default:
}