如何从goroutine中返回多个值?

huangapple go评论114阅读模式
英文:

How to return multiple values from goroutine?

问题

我找到了一个关于“从 Goroutines 中捕获值”的示例,链接

示例中展示了如何获取值,但如果我想从多个 Goroutines 中返回值,它将无法工作。所以,有人知道如何做吗?

  1. package main
  2. import (
  3. "fmt"
  4. "io/ioutil"
  5. "log"
  6. "net/http"
  7. "sync"
  8. )
  9. // WaitGroup 用于等待程序完成 Goroutines。
  10. var wg sync.WaitGroup
  11. func responseSize(url string, nums chan int) {
  12. // 调用 WaitGroup 的 Done 方法告诉 Goroutine 已完成。
  13. defer wg.Done()
  14. response, err := http.Get(url)
  15. if err != nil {
  16. log.Fatal(err)
  17. }
  18. defer response.Body.Close()
  19. body, err := ioutil.ReadAll(response.Body)
  20. if err != nil {
  21. log.Fatal(err)
  22. }
  23. // 将值发送到无缓冲通道
  24. nums <- len(body)
  25. }
  26. func main() {
  27. nums := make(chan int) // 声明一个无缓冲通道
  28. wg.Add(1)
  29. go responseSize("https://www.golangprograms.com", nums)
  30. go responseSize("https://gobyexample.com/worker-pools", nums)
  31. go responseSize("https://stackoverflow.com/questions/ask", nums)
  32. fmt.Println(<-nums) // 从无缓冲通道中读取值
  33. wg.Wait()
  34. close(nums) // 关闭通道
  35. // >> 永远加载中
  36. }

另外,这个例子是关于worker pools的。

fmt.Println(<-results) 这行代码中获取值是不可能的,会导致错误。

英文:

I found some example with "Catch values from Goroutines"-> link

There is show how to fetch value but if I want to return value from several goroutines, it wont work.So, does anybody know, how to do it?

  1. package main
  2. import (
  3. &quot;fmt&quot;
  4. &quot;io/ioutil&quot;
  5. &quot;log&quot;
  6. &quot;net/http&quot;
  7. &quot;sync&quot;
  8. )
  9. // WaitGroup is used to wait for the program to finish goroutines.
  10. var wg sync.WaitGroup
  11. func responseSize(url string, nums chan int) {
  12. // Schedule the call to WaitGroup&#39;s Done to tell goroutine is completed.
  13. defer wg.Done()
  14. response, err := http.Get(url)
  15. if err != nil {
  16. log.Fatal(err)
  17. }
  18. defer response.Body.Close()
  19. body, err := ioutil.ReadAll(response.Body)
  20. if err != nil {
  21. log.Fatal(err)
  22. }
  23. // Send value to the unbuffered channel
  24. nums &lt;- len(body)
  25. }
  26. func main() {
  27. nums := make(chan int) // Declare a unbuffered channel
  28. wg.Add(1)
  29. go responseSize(&quot;https://www.golangprograms.com&quot;, nums)
  30. go responseSize(&quot;https://gobyexample.com/worker-pools&quot;, nums)
  31. go responseSize(&quot;https://stackoverflow.com/questions/ask&quot;, nums)
  32. fmt.Println(&lt;-nums) // Read the value from unbuffered channel
  33. wg.Wait()
  34. close(nums) // Closes the channel
  35. // &gt;&gt; loading forever

Also, this example, worker pools

Is it possible to get value from result: fmt.Println(&lt;-results) <- will be error.

答案1

得分: 3

是的,只需多次从通道中读取即可:

  1. answerOne := <-nums
  2. answerTwo := <-nums
  3. answerThree := <-nums

通道的功能类似于线程安全的队列,允许您将值排队并逐个读取出来。

附注:您应该将等待组增加3次,或者根本不使用等待组。<-nums 将会阻塞,直到 nums 上有一个可用的值,因此不需要等待组。

英文:

Yes, just read from the channel multiple times:

  1. answerOne := &lt;-nums
  2. answerTwo := &lt;-nums
  3. answerThree := &lt;-nums

Channels function like thread-safe queues, allowing you to queue up values and read them out one by one

P.S. You should either add 3 to the wait group or not have one at all. The <-nums will block until a value is available on nums so it is not necessary

huangapple
  • 本文由 发表于 2022年9月3日 06:32:23
  • 转载请务必保留本文链接:https://go.coder-hub.com/73588427.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定