跑两个gorouting 执行如下代码:
func main() {
runtime.GOMAXPROCS(1)
ch := make(chan int)
go print(ch)
go print(ch)
for i := 0; i < 2; i++ {
<-ch
}
}
func print(ch chan int) {
// dosomething
for i := 0; i < 10; i++ {
fmt.Println(i)
}
ch <- 0
}
打印结果:0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9
两个gorouting顺序执行。
让gorouting出让cup使用权:
func print(ch chan int) {
// dosomething
for i := 0; i < 10; i++ {
if i == 5 {
time.Sleep(time.Second) // 出让cpu使用给其他gorouting
}
fmt.Printf(" %d", i)
}
ch <- 0
}
打印结果:0 1 2 3 4 0 1 2 3 4 5 6 7 8 9 5 6 7 8 9
总结:两个gorouting在一个os线程中跑。若当前gorouting不发生阻塞,不会出让cpu给其他使用,所有例一会顺序打印。当gorouting 中执行sleep时,出让使用权给其他gorouting(或者使用runtime.Gosched(),形成逻辑上的并行,也就是并发。
顺便回顾下runtime调度器几个函数:
Gosched
让出cpuNumCPU
返回当前系统的CPU核数量GOMAXPROCS
设置最大的可同时使用的CPU核数Goexit
退出当前goroutine(但是defer语句会照常执行)
那么关于我们开启多核的时候呢?Go语言对goroutine的调度行为又是怎么样的?
当一个goroutine发生阻塞,Go会自动地把与该goroutine处于同一os线程的其他goroutines转移到另一个系统线程上去,以使这些goroutines不阻塞
0