1 回答

TA貢獻2039條經驗 獲得超8個贊
問題是它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 關注
- 259 瀏覽
添加回答
舉報