具有并发性示例的值不正确

时间:2018-06-02 20:49:43

标签: go concurrency

我正在通过电子书工作,在这里我正在执行此代码:

func f(n int) {
  for i := 0; i < 10; i++ {
    fmt.Println(n, ":", i)
    amt := time.Duration(rand.Intn(250))
    time.Sleep(time.Millisecond * amt)
  }
}

func ConcurrMain() {
  for i := 0; i < 10; i++ {
    go f(i)
  }
  fmt.Println("hi")
}

问题是我通过goclipse的每个运行命令检索不同的值。当我不执行sleep命令时似乎工作得更好。

在任何情况下,我认为一步一步的解释在我学习并发性方面是有益的

这是我的时间睡眠回报值的一个例子:

4 : 0
1 : 0
6 : 0
0 : 0
5 : 0
7 : 0
8 : 0
2 : 0
3 : 0
9 : 0
9 : 1
hi

然后我再次运行它,我现在有时间睡觉:

0 : 0
hi
1 : 0

现在第三次和我一起睡觉时间:

0 : 0
hi

这次不睡觉我得到:

1 : 0
1 : 1
1 : 2
1 : 3
1 : 4
1 : 5
1 : 6
1 : 7
1 : 8
3 : 0
3 : 1
4 : 0
4 : 1
4 : 2
9 : 0
6 : 0
6 : 1
6 : 2
2 : 0
2 : 1
2 : 2
2 : 3
2 : 4
2 : 5
2 : 6
2 : 7
2 : 8
2 : 9
7 : 0
7 : 1
7 : 2
7 : 3
7 : 4
7 : 5
7 : 6
5 : 0
5 : 1
5 : 2
5 : 3
5 : 4
5 : 5
5 : 6
5 : 7
5 : 8
5 : 9
9 : 1
1 : 9
8 : 0
3 : 2
hi

我在Windows下使用goclipse以防信息相关

更新

应该注意,此调用从主程序包调用为:

func main()
{
   lab.ConcurrMain()
}

UPDATE2

我添加了:var wg sync.WaitGroup outside the func scope. I also added wg.Add(1)inside the ConcurrMain method just prior to go f(i), then i also added wg.Wait()just after the forloop执行go函数and then finally wg.Done()inside the f()`方法**,这似乎有效,但答案不在电子书中,所以我想理解。

1 个答案:

答案 0 :(得分:1)

在go中,一个程序只在它运行的主要goroutine运行时运行。也就是说,最初运行main函数的goroutine,如果退出,整个程序退出。

在您最初提供的示例(代码片段)中,当在ConcurrMain中启动的goroutines将安排时,没有任何内容可以强制执行跑。在添加sync.WaitGroup之前,主goroutine可以在安排其他goroutine之前退出。

如果主goroutine退出,整个程序退出,其他goroutine将不会执行。主要的goroutine将不会等待其他goroutine,除非你特别要求它与一个等待组。