zoukankan      html  css  js  c++  java
  • [golang学习] goroutine调度

    这两天有些闲功夫, 学习下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在后续版本中应该会持续改进调度器.

  • 相关阅读:
    百度云人脸识别API人脸库管理
    百度云人脸识别API人脸对比
    Linux之find命令
    Linux之grep命令
    Linux之sed命令
    LNMP Shell脚本发布
    auto_modify_ip Shell脚本安装
    JVM虚拟机详解+Tomcat性能优化
    Tomcat连接器详解
    Tomcat配置详解
  • 原文地址:https://www.cnblogs.com/lingdhox/p/4189505.html
Copyright © 2011-2022 走看看