使用WaitGroup例程中的通道填充数组

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

Populating an array using Channels in a WaitGroup routine

问题

我想在一个子程序中填充一个数组的数组。我尝试使用通道来实现这个目标。我正在学习Go语言,所以不确定这是否是正确的方法,请纠正我如果我走错了方向,但是我的代码从来没有返回。我做错了什么?

  1. var c = make(chan [3][4]string)
  2. var mymap = map[int]string{
  3. 0: "www.foo.com",
  4. 1: "www.bar.com",
  5. 2: "www.baz.com",
  6. 3: "www.faz.com",
  7. }
  8. values := [3][4]string{{"A", "B", "C", "D"}}
  9. var wg sync.WaitGroup
  10. wg.Add(4) // 每个索引一个线程,总共4个索引
  11. for idx, url := range mymap {
  12. go func(idx int, url string) {
  13. defer wg.Done()
  14. values[1][idx] = "someone"
  15. values[2][idx] = "something"
  16. c <- values
  17. }(name, url)
  18. }
  19. wg.Wait()
  20. close(c)
英文:

I want to populate an array of arrays inside a subroutine. I am trying to do this using a channel. I am learning go, so unclear if this is the right way, so please correct me if I am going in the wrong direction, but my code never returns. What am I doing wrong?

  1. var c = make(chan [3][4]string)
  2. var mymap = map[int]string{
  3. 0: &quot;www.foo.com&quot;,
  4. 1: &quot;www.bar.com&quot;,
  5. 2: &quot;www.baz.com&quot;,
  6. 3: &quot;www.faz.com&quot;,
  7. }
  8. values := [3][4]string{{&quot;A&quot;, &quot;B&quot;, &quot;C&quot;, &quot;D&quot;}}
  9. var wg sync.WaitGroup
  10. wg.Add(4) // one thread per index, total 4 indexes
  11. for idx, url := range mymap {
  12. go func(idx int, url string) {
  13. defer wg.Done()
  14. values[1][idx] = &quot;someone&quot;
  15. values[2][idx] = &quot;something&quot;
  16. c &lt;- values
  17. }(name, url)
  18. }
  19. wg.Wait()
  20. close(c)

答案1

得分: 2

从代码中看,似乎没有读取通道c的操作,代码在那里卡住了。

这段代码不需要任何同步(通道等),因为每个goroutine都在处理values的不同部分,gr1-> [xx,0],gr2-> [xx,1],gr3-> [xx,2],gr4-> [xx,3]。

只需从代码中移除通道c,这样应该就可以正常工作了。

将goroutine代码更改为:

  1. go func(idx int, url string, arr *[3][4]string) {
  2. defer wg.Done()
  3. arr[1][idx] = "someone"
  4. arr[2][idx] = "something"
  5. }(idx, url, &values)
英文:

From code it looks like channel c is not read, and code is stuck there.

This code doesn't need any synchronisation (channel etc.) because each goroutine is working on different part of values, gr1->[xx,0], gr2->[xx,1], gr3-> [xx,2], gr4-> [xx,3].

Just remove the channel c from the code and this should work fine.

Change goroutine code to:

  1. go func(idx int, url string, arr *[3][4]string) {
  2. defer wg.Done()
  3. arr[1][idx] = &quot;someone&quot;
  4. arr[2][idx] = &quot;something&quot;
  5. }(idx, url, &amp;values)

答案2

得分: 0

根据之前的回答,你的通道没有被读取。

然而,如果你对通道进行缓冲(在你的情况下缓冲大小为4),代码应该能够完成。

另外,移除通道也是可行的解决方案。我不确定为什么你要将整个构建的数组传递给通道。我猜你是在检查数组如何被改变以及程序如何工作的。

英文:

As previous answer states, you channel is not read.

However, if you buffer your channel (buffer of 4 in your case) the code should finish.

Also removing the channel is viable solution. I am not sure why you pass the whole array you are building to the channel. I assume you examining how the array gets changed and how the routines work.

huangapple
  • 本文由 发表于 2022年9月19日 12:11:48
  • 转载请务必保留本文链接:https://go.coder-hub.com/73768425.html
匿名

发表评论

匿名网友

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

确定