1 回答
TA贡献2039条经验 获得超7个赞
问题是它sizes不是一个 buffered chan,所以只有一个匿名 goroutines 可以在sizes需要读取之前实际完成。这会wg.Wait()导致永远等待(因为下一个 goroutine 正在阻塞sizes <-并且不能defer wg.Done())和死锁。
通过将 close 放入单独的 goroutine 中,它可以在sizes准备好时关闭chan,并sizes在两者之间进行处理。最终,这是 goroutine 的一个很好的用途——触发并忘记关闭!
为了让这段代码在没有更接近的 goroutine 的情况下工作,你可以简单地初始化sizes为一个缓冲的 chan,缓冲区 >= 的长度filenames。
func makeThumbnails(filenames <-chan string, result chan<- int64) int64 {
sizes := make(chan int64, 10) // buffered channel, now!
// if filenames sends more than 10 strings, though, we're in trouble!!
var wg sync.WaitGroup
for f := range filenames {
wg.Add(1)
go func(f string) {
defer wg.Done()
sizes <- int64(len(f))
}(f)
}
// **closer**, this guy doesn't need to be a goroutine!!
wg.Wait()
close(sizes)
var total int64
for size := range sizes {
total += size
}
result <- total
return total
}
但是,由于filenames的长度在运行时是不可知的,因此不可能轻松做到这一点。你必须通读filenames,将其存储到一个切片,然后初始化大小和for在range filenamesSlice与....是啊基本上你只是重新写在该点的整体功能。
- 1 回答
- 0 关注
- 226 浏览
添加回答
举报