[golang学习] goroutine调度

lingdhox · · 2541 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

这两天有些闲功夫, 学习下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都没有机会执行. 

我在询问了某个人之后, 加上这句. 

这是设置go的os线程数. 

但这样出来的结果就有点奇怪, 有时候会输出100个k, 有时候会输出50个k. 或者干脆一个k都没有. 

为什么呢?

因为我们无法控制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在后续版本中应该会持续改进调度器.


有疑问加站长微信联系

本文来自:博客园

感谢作者:lingdhox

查看原文:[golang学习] goroutine调度

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:812540095

2541 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传