runtime.Gosched
标准库注释翻译: Gosched放弃了处理器,允许其他goroutines运行。它不会挂起当前例程,会自动恢复。
通俗翻译:让出CPU"时间片",重新等待安排任务
func main() {
go func(s string) {
for i := 0; i < 3; i++ {
fmt.Println(s)
}
}("goroutinue 1")
go func() {
time.Sleep(1 * time.Second)
fmt.Println("xxxx")
}()
for i := 0; i < 3; i++ {
fmt.Println("main goroutinue")
runtime.Gosched() // 让出CPU时间片,重新等待安排任务
}
time.Sleep(2 * time.Second)
}
这里会输出
main goroutinue
goroutinue 1
goroutinue 1
goroutinue 1
main goroutinue
main goroutinue
xxxx
在主协程让出CPU时间片后,最终"xxxx"字符串也是输出到了"main goroutinue"字符串后面,说明让出了CPU时间片,并不是一味着阻塞等待其它协程执行完毕再执行
runtime.Goexit
退出当前协程
func main() {
go func(s string) {
for i := 0; i < 3; i++ {
fmt.Println(s)
runtime.Goexit() //退出协程 不要在主协程上设置哈,会崩
}
}("goroutinue 1")
for i := 0; i < 3; i++ {
fmt.Println("main goroutinue")
}
time.Sleep(2 * time.Second)
}
输出
main goroutinue
main goroutinue
main goroutinue
goroutinue 1
runtime.GOMAXPROCS
Go运行时调度器使用runtime.GOMAXPROCS参数来确定需要使用多少个os线程来同时执行go代码,"默认值"是机器上的CPU"逻辑"核心数
var wg sync.WaitGroup
func a() {
defer wg.Done()
for i := 0; i < 100000000; i++ {
}
}
func b() {
defer wg.Done()
for i := 0; i < 100000000; i++ {
}
}
func main() {
startTime := time.Now()
// runtime.GOMAXPROCS(1)
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))
}
指定1核运算时 201.8216ms 我电脑是4核,默认是35.1641ms
runtime.GOOS
正在运行的程序的操作系统目标,一个字符串常量
runtime.Stack / runtime.Caller(类似)
获取栈帧信息
第一个参数要传入一个分配了内存的数组/切片,第二个参数true会输出所有的goroutine信息
func main() {
var buf = make([]byte, 64) // var buf []byte 这样是不行的
// 参考 https://www.jianshu.com/p/1df83dc0ec49
runtime.Stack(buf, false)
fmt.Println(string(buf))
}
goroutine 1 [running]:
main.main()
D:/www/peak/etc/qt.go:10 +0x
runtime.KeepAlive
这个用的不太多 Go ballast
可参考 https://mp.weixin.qq.com/s/gc34RYqmzeMndEJ1-7sOwg
ballast := make([]byte, 4*1024*1024*1024) // 1G
runtime.KeepAlive(ballast)