package main
import (
"sync"
"runtime"
)
type S struct {
chs chan int
}
var wg sync.WaitGroup
func worker(s *S) {
for i := range s.chs {
println("In worker, ch = ", i)
}
wg.Done()
}
func main() {
s := S{make(chan int)}
runtime.SetFinalizer(&s, func(ss *S) {
println("Finalizer")
close(ss.chs)
})
wg.Add(1)
go worker(&s)
for i := 0; i < 1; i++ {
s.chs <- 1
}
runtime.GC()
wg.Wait()
}
Изход (отидете 1.8.3):
В работник, ch = 1
Финализатор
Очаквам тази програма да блокира. runtime.GC()
няма да събира s
, тъй като worker()
съдържа препратка към s.chs
.
Той обаче завършва с go 1.8.3. Във финализатора на s
дори close(s.chs)
се извиква успешно.
Чудя се дали има нещо специално общо с range
и GC.
Много благодаря.
s
няма да се използва отново. Направетеs
глобален и той ще блокира. - person JimB   schedule 07.09.2017Close()
за типове, които обвиват FD и сокети. Вижте също. - person kostix   schedule 08.09.2017