golang中的runtime包
1. runtime.Gosched 让出CPU时间片,重新等待安排任务
package main import ( "fmt" "runtime" ) func main() { go func(s string) { for i :=0; i < 2; i++ { fmt.Println(s) runtime.Gosched() // 让出CPU时间片,重新等带安排任务 } }("world") for i := 0; i < 2; i++ { fmt.Println("hello") runtime.Gosched() // 让出CPU时间片,重新等待安排任务 } }
2. runtime.Goexit 退出当前协程
package main import ( "fmt" "runtime" "sync" ) var wg sync.WaitGroup func main() { wg.Add(1) go func() { defer wg.Done() defer fmt.Println("A.defer") func() { defer fmt.Println("B.defer") // 结束协程 runtime.Goexit() defer fmt.Println("C.defer") fmt.Println("B") }() fmt.Println("A") }() wg.Wait() // 主goroutine等待子goroutine结束,主在结束 }
3. runtime.GOMAXPROCS
Go运行时调度器使用runtime.GOMAXPROCS参数来确定需要使用多少个os线程来同时执行go代码,
默认值是机器上的CPU核心数量,例如一个8核心的机器上,调度器会把go代码同时调度到8个os线程上,
(GOMAXPROCS是m:n调度中的n)
go语言中可以通过runtime.GOMAXPROCS()函数来设置当前程序并发时占用的CPU逻辑核心数
go1.5版本之前默认使用的是单核心执行,1.5之后默认使用全部的cpu逻辑核心数
我们可以通过将任务分配到不同的CPU逻辑核心上,从而实现并行的效果
package main import ( "fmt" "runtime" "sync" "time" ) var wg sync.WaitGroup func a() { defer wg.Done() for i := 0; i < 100000000; i++ { //fmt.Println("A", i) } } func b() { defer wg.Done() for i := 0; i < 100000000; i++ { //fmt.Println("B", i) } } func main() { startTime := time.Now() //runtime.GOMAXPROCS(1) // 设置go运行时(runtime)的os线程数 // runtime.GOMAXPROCS设置为1os线程数时执行时间要比4os线程数用时更长 runtime.GOMAXPROCS(4) // 设置go运行时(runtime)的os线程数 wg.Add(1) go a() wg.Add(1) go b() wg.Add(1) go a() wg.Add(1) go b() wg.Wait() fmt.Println(time.Now().Sub(startTime)) }
运行结论:runtime.GOMAXPROCS设置为1os线程数时执行时间要比4os线程数用时更长
1os线程数执行时耗时:320ms左右,4os线程数执行耗时:160ms左右,不同系统运行时不太一样
因为: 1os线程数goroutine只能是并发执行,而4os线程数goroutine可以并行执行,所以快。
总结:
runtime.Gosched() 让出cpu时间片,等待重新分配任务
runtiem.Goexit() 退出协程
runtime.GOMAXPROCS(i int) 执行go程序时对应的os线程数,即m:n中的n值