亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

Sync.WaitGroup,為什么在 goroutine 中更接近

Sync.WaitGroup,為什么在 goroutine 中更接近

Go
米琪卡哇伊 2021-12-07 10:39:11
下面是 Go 編程書中的示例代碼。我不明白為什么 close 需要是它自己的 goroutine。我試圖靠近主,但它崩潰了。有人可以解釋為什么更接近的需要在一個單獨的 goroutine 中?謝謝!func makeThumbnails(filenames <-chan string, result chan<- int64) int64 {  sizes := make(chan int64)  var wg sync.WaitGroup  for f := range filenames {      wg.Add(1)      go func(f string) {        defer wg.Done()        sizes <- int64(len(f))      }(f)  }  // **closer**, why this guy needs to be in a goroutine???  go func() {    wg.Wait()    close(sizes)  }()  var total int64  for size := range sizes {    total += size  }  result <- total  return total}
查看完整描述

1 回答

?
largeQ

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與....是啊基本上你只是重新寫在該點的整體功能。


查看完整回答
反對 回復 2021-12-07
  • 1 回答
  • 0 關注
  • 259 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號