这两天有些闲功夫, 学习下golang, 确实很是简洁. golang
不过有些缺憾. 在个人测试中. golang的调度(goroutine)彷佛不是很是好. 源码分析
func say(k int) { fmt.Println(k) } func main() { runtime.GOMAXPROCS(2) for i := 0; i < 100; i++ { go say(i) } for { } }
这段测试代码是有bug的.学习
一开始我并无设置测试
runtime.GOMAXPROCS(2)
则因为for循环致使主线程阻塞. 全部的goroutine都没有机会执行. spa
我在询问了某我的以后, 加上这句. 线程
这是设置go的os线程数. code
但这样出来的结果就有点奇怪, 有时候会输出100个k, 有时候会输出50个k. 或者干脆一个k都没有. blog
为何呢?队列
由于咱们没法控制goroutine会被分配在哪一个 os线程上. 源码
因此惟一(我所能查阅到的资料) 的解决办法是在for循环中主动交出控制权. 使同一个 os线程上的goroutine有机会被执行.
像下面这样:
for {
runtime.GOMAXPROCS(2)
}
这里有一篇详细的关于go 调度器的解释:
http://morsmachine.dk/go-scheduler
也就是golang 中的每一个os线程对应的goroutine队列, 在某个线程阻塞时会发生切换. 切换到其余其余线程执行. 但这个每每发生在I/O和系统调用时.
那为何纯粹的for循环阻塞时 golang没法把goroutine切换到其余线程执行呢?
由于go本身实现的I/O和系统调用 内部会自动调用runtime.GOMAXPROCS(2)
以上没有源码分析做为支持. 可能会有谬误. 请告诉我.
golang在后续版本中应该会持续改进调度器.