我正在通过电子书工作,在这里我正在执行此代码:
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()`方法**,这似乎有效,但答案不在电子书中,所以我想理解。
答案 0 :(得分:1)
在go中,一个程序只在它运行的主要goroutine运行时运行。也就是说,最初运行main函数的goroutine,如果退出,整个程序退出。
在您最初提供的示例(代码片段)中,当在ConcurrMain
中启动的goroutines将安排时,没有任何内容可以强制执行跑。在添加sync.WaitGroup
之前,主goroutine可以在安排其他goroutine之前退出。
如果主goroutine退出,整个程序退出,其他goroutine将不会执行。主要的goroutine将不会等待其他goroutine,除非你特别要求它与一个等待组。