簡體   English   中英

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

[英]Sync.WaitGroup, why closer in a goroutine

以下是Go編程手冊中的示例代碼。 我不明白為什么閉合器需要自己的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
}

問題是, sizes是不是一個緩沖chan ,所以只能匿名夠程前能實際完成的一個sizes需要被讀取。 這使wg.Wait()永遠等待(因為下一個goroutine在sizes <-上阻塞,並且不能defer wg.Done() )和死鎖。

通過將關閉器投入一個單獨的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 ,將其存儲到一個切片,然后初始化大小和forrange filenamesSlice和....是啊基本上你只是重新寫在該點的整體功能。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM