内容简介:尽管 Go 编译器产生的是本地可执行代码,这些代码仍旧运行在 Go 的 runtime(这部分的代码可以在 runtime 包中找到)当中。这个 runtime 类似 Java 和 .NET 语言所用到的虚拟机,它负责管理包括内存分配、垃圾回收(第 10.8 节)、栈处理、goroutine、channel、切片(slice)、map 和反射(reflection)等等。运行结果:
尽管 Go 编译器产生的是本地可执行代码,这些代码仍旧运行在 Go 的 runtime(这部分的代码可以在 runtime 包中找到)当中。这个 runtime 类似 Java 和 .NET 语言所用到的虚拟机,它负责管理包括内存分配、垃圾回收(第 10.8 节)、栈处理、goroutine、channel、切片(slice)、map 和反射(reflection)等等。
runtime
调度器是个非常有用的东西,关于 runtime
包几个方法:
-
Gosched:让当前线程让出
cpu
以让其它线程运行,它不会挂起当前线程,因此当前线程未来会继续执行 -
NumCPU:返回当前系统的
CPU
核数量 -
GOMAXPROCS:设置最大的可同时使用的
CPU
核数 -
Goexit:退出当前
goroutine
(但是defer
语句会照常执行) -
NumGoroutine:返回正在执行和排队的任务总数
-
GOOS:目标操作系统
NumCPU
package main import ( "fmt" "runtime" ) func main() { fmt.Println("cpus:", runtime.NumCPU()) fmt.Println("goroot:", runtime.GOROOT()) fmt.Println("archive:", runtime.GOOS) }
运行结果:
image.png
GOMAXPROCS
Golang
默认所有任务都运行在一个 cpu
核里,如果要在 goroutine
中使用多核,可以使用 runtime.GOMAXPROCS
函数修改,当参数小于 1 时使用默认值。
package main import ( "fmt" "runtime" ) func init() { runtime.GOMAXPROCS(1) } func main() { // 任务逻辑... }
Gosched
这个函数的作用是让当前 goroutine
让出 CPU
,当一个 goroutine
发生阻塞, Go
会自动地把与该 goroutine
处于同一系统线程的其他 goroutine
转移到另一个系统线程上去,以使这些 goroutine
不阻塞。
注意关闭通道使用的是 close()
方法。
引申思考:close()关闭通道的时候,如果关闭一个已经关闭的通道,会报错。那我们关闭时如何确定通道此时的状态呢?
这里有一篇文章大家可以参考下
https://www.jianshu.com/p/d24dfbb33781package main import ( "fmt" "runtime" ) func init() { runtime.GOMAXPROCS(1) //使用单核 } func main() { exit := make(chan int) go func() { defer close(exit) go func() { fmt.Println("b") }() }() for i := 0; i < 4; i++ { fmt.Println("a:", i) if i == 1 { runtime.Gosched() //切换任务 } } <-exit }
结果:
image.png
使用多核测试:
package main import ( "fmt" "runtime" ) func init() { runtime.GOMAXPROCS(4) //使用多核 } func main() { exit := make(chan int) go func() { defer close(exit) go func() { fmt.Println("b") }() }() for i := 0; i < 4; i++ { fmt.Println("a:", i) if i == 1 { runtime.Gosched() //切换任务 } } <-exit }
结果:
image.png
根据你机器来设定运行时的核数,但是运行结果不一定与上面相同,或者在 main
函数的最后加上 select{} 让程序阻塞,则结果如下:
image.png
多核比较适合那种 CPU
密集型程序,如果是 IO
密集型使用多核会增加 CPU
切换的成本。
Gosched再说明
Gosched用来让出CPU的时间片。就像是接力赛跑,A跑了一会碰到 runtime.Gosched()
,就会把时间片给B,让B接着跑。
package main import ( "runtime" "fmt" ) func init() { runtime.GOMAXPROCS(1) } func say(s string){ for i := 0; i < 2; i++ { runtime.Gosched() fmt.Println(s) } } func main() { go say("world") say("hello") }
输出结果:
hello
world
hello
注意结果:
1、先输出了hello,后输出了world.
2、hello输出了2个,world输出了1个(因为第2个hello输出完,主线程就退出了,第2个world没机会了)
把代码中的runtime.Gosched()注释掉,执行结果是:
hello
hello
因为say("hello")这句占用了时间,等它执行完,线程也结束了,say("world")就没有机会了。
这里同时可以看出,go中的goroutins并不是同时在运行。事实上,如果没有在代码中通过
runtime.GOMAXPROCS(n) 其中n是整数,
指定使用多核的话,goroutins都是在一个线程里的,它们之间通过不停的让出时间片轮流运行,达到类似同时运行的效果。
以上所述就是小编给大家介绍的《golang中的runtime包教程》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 立体字母建模教程【C4D教程】
- PS学习教程 PS制作字体发光效果教程
- 【C4D教程】卡通风可爱小乌龟建模教程
- 卡通风仙人掌建模教程【C4D教程】
- 3D立体字体制作教程,C4D建模教程
- 3D小乌龟制作教程,C4D建模教程
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Designing for Emotion
Aarron Walter / Happy Cog / 2011-10-18 / USD 18.00
Make your users fall in love with your site via the precepts packed into this brief, charming book by MailChimp user experience design lead Aarron Walter. From classic psychology to case studies, high......一起来看看 《Designing for Emotion》 这本书的介绍吧!