我有一个golang代码示例如下(xx.go):
package main
import "runtime"
func main() {
c2 := make(chan int)
go func() {
for v := range c2 {
println("c2 =", v, "numof routines:", runtime.NumGoroutine())
}
}()
for i:=1;i<=10001;i++{
c2 <- i
//runtime.Gosched()
}
}
为什么?
我测试的数字从小到2到大到10000,它们都遵守上述规则!
ENV如下: uname -a : Linux hadoopnode25232 2.6.18-308.16.1.el5 #1 SMP Tue Oct 2 22:01:43 EDT 2012 x86_64 x86_64 x86_64 GNU/Linux
go version : go version go1.1 linux/amd64
我认为这与go sched有关。
我汇编代码:
go tool 6g -S xx.go > xx.s
10000和10001之间的唯一区别是:
33c33
< 0030 (xx.go:20) CMPQ AX,$10001
---
> 0030 (xx.go:20) CMPQ AX,$10000
最后但并非最不重要的是,当我添加runtime.Gosched()
时,一切运行良好。
答案 0 :(得分:1)
当main返回时,程序终止。它不会等待任何goroutines完成。因此,所有goroutine是否及时完成取决于调度程序,以及相当长的随机性,巧合和外部因素。 1e4和1e4 + 1次迭代之间的差异可能是那些影响调度的因素之一,只有那一点能够及时完成goroutine。
如果你真的需要在退出之前完成goroutine,请等待它完成,例如使用sync.WaitGroup。
与实际问题无关,您的代码过于复杂且对其正在进行的操作非常简单。您可以按如下方式重写goroutine函数:
for v := range c2 {
println("c2 =", v,"numof routines:",runtime.NumGoroutine())
}
答案 1 :(得分:0)
等待goroutine完成后你需要睡一秒钟或阻止一段时间!!
答案 2 :(得分:0)
“go”语句开始执行函数调用 独立的并发控制线程,或goroutine,在 相同的地址空间。
GoStmt = "go" Expression .
功能值和参数按照常规进行评估 调用goroutine,但不像常规调用,程序执行 不等待调用的函数完成。
一旦最终发送c2 <- i
完成,程序可以终止,它不必等待被调用的函数完成。您只能保证在测试中完成执行接收v, ok := <-c2
,c - 1次,其中c是您的循环计数,10000或10001。