Golang runtime.Gosched()函数浅析

分类:技术文档 - Golang | 阅读(118) | 发布于:2019-05-08 10:39

以下是官方的定义:
// Gosched yields the processor, allowing other goroutines to run. It does not
// suspend the current goroutine, so execution resumes automatically.
func Gosched() {
    mcall(gosched_m)
}

这个函数的作用是让当前goroutine让出CPU,好让其它的goroutine获得执行的机会。同时,当前的goroutine也会在未来的某个时间点继续运行。
请看下面这个例子

package main
import (
	"fmt"
	//"runtime"
)
func say(s string) {
	for i := 0; i < 2; i++ {
		//runtime.Gosched()
		fmt.Println(s, i)
	}
}
func main() {
	go say("world")
	say("hello")
}
//执行输出:
//hello 0
//hello 1

---------取消注释runtime.Gosched()---------

package main
import (
	"fmt"
	"runtime"
)
func say(s string) {
	for i := 0; i < 2; i++ {
		runtime.Gosched()
		fmt.Println(s, i)
	}
}
func main() {
	go say("world")
	say("hello")
}
//执行输出:
//hello 0
//world 0
//hello 1

可以看到使用runtime.Gosched()后,先输出"hello 0",再输出"world 0",再输出"hello 1",最后一个"world 1"没有机会输出线程就结束了。

再看下面这个例子:

package main
import "fmt"
func showNumber (i int) {
	fmt.Println(i)
}
func main() {
	for i := 0; i < 10; i++ {
		go showNumber(i)
	}
	fmt.Println("Haha")
}
//执行输出:
//Haha

---------使用runtime.Gosched()---------

package main
import (
	"fmt"
	"runtime"
)
func showNumber(i int) {
	fmt.Println(i)
}
func main() {
	for i := 0; i < 10; i++ {
		go showNumber(i)
	}
	runtime.Gosched()
	fmt.Println("Haha")
}
//执行输出:(每次结果不一定,但"Haha"一定输出且在最后)
//6
//3
//7
//1
//8
//9
//4
//0
//2
//5
//Haha

分析:默认情况goroutins都是在一个线程里执行的,多个goroutins之间轮流执行,当一个goroutine发生阻塞,Go会自动地把与该goroutine处于线程的其他goroutines转移到另一个线程上去,以使这些goroutines不阻塞。 通过上面的结果可以看出,主线程执行完毕之后程序就退出了。 最后,如果代码中通过 runtime.GOMAXPROCS(n) 其中n是整数,指定使用多核的话,多个goroutines之间就可以实现真正的并行,结果就会上面的有所不同。

标签: