1.goruntine调用匿名函数
package main
import (
"fmt"
"runtime"
"time"
)
func print(i int){
fmt.Print(i,"\t")
}
func foo() {
//runtime.GOMAXPROCS(1) //单核
time.Sleep(time.Second)
for i := 0; i < 50; i++ {
go func() {
fmt.Print(i,"\t")
}()
//go print(i)
}
runtime.Gosched()
time.Sleep(time.Second)
}
func main(){
foo()
}
// 运行结果大部分是50,相对应for 循环 goroutine跑的慢
2 14 14 14 14 15 15 16 17 18 18 18 18 19 19 20 21 21 21 21 22
23 26 26 26 26 42 46 46 46 50 50 50 50 46 50 50 50 50 46 50 38
50 50 50 50 46 50 50 50
// 单核运行结果全部是50,相对应for 循环 goroutine跑的慢
50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50
50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50
50 50 50 50 50 50 50 50
2.goruntine调用普通函数
package main
import (
"fmt"
"runtime"
"time"
)
func print(i int){
fmt.Print(i,"\t")
}
func foo() {
//runtime.GOMAXPROCS(1) //单核
time.Sleep(time.Second)
for i := 0; i < 50; i++ {
//go func() {
//fmt.Print(i,"\t")
//}()
go print(i)
}
runtime.Gosched()
time.Sleep(time.Second)
}
func main(){
foo()
}
// 运行结果,这是因为有个参数i需要压栈需要获取i的值
0 10 4 5 6 7 8 2 13 17 15 18 12 9 1 11 14 22 19 20
21 16 23 24 25 3 49 38 39 40 41 42 43 44 45 26 47 28 29 27
46 36 32 37 33 30 34 35 31 48
// 单核运行结果,这是因为有个参数i需要压栈需要获取i的值
49 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
39 40 41 42 43 44 45 46 47 48
//是49 - 0...8并不是0...49,这是为什么呢?
//其实,go 在把 goroutine放入队列(gosched内容会有另外的篇幅来说明)的时候还做了
//一件很特别的事:proc:4799 (next),代码内容如下:
if next {
retryNext:
oldnext := _p_.runnext
if !_p_.runnext.cas(oldnext, guintptr(unsafe.Pointer(gp))) {
goto retryNext
}
if oldnext == 0 {
return
}
// Kick the old runnext out to the regular run queue.
gp = oldnext.ptr()
}
//这段代码的意思是 go 会把每个 P 所管理的最后一个 goroutine 放入 next 位置。为什么??
//这是 go 设计认为或者是有过测试:如果一个 P 的 goroutine 队列在顺序执行的时候,
//因为 go sched 会有很多抢占或者调度。那么从被执行的概率上来分析的话,放入一个
//next 位置可使得每个 goroutine 的执行概率是相当的。
//这个next的位置也就决定了49为什么最先打印。
go func(i int) {
fmt.Print(i,"\t")
}(i)
等效于go print(i)