zoukankan      html  css  js  c++  java
  • Go 1.14之前的死循环Case

    第一个例子

    package main
    
    import (
        "runtime"
        "time"
    )
    
    func main() {
        runtime.GOMAXPROCS(1)
        go func() {
            for {
            }
        }()
        time.Sleep(time.Millisecond)
        println("OK")
    }
    

    不会打印OK

    关于 Go1.14,你一定想知道的性能提升与新特性

    为什么不会打印?

    > [golang高并发模型](https://www.yangyanxing.com/article/golang-concurrency.html)

    第二个例子

    package main
    
    import (
    	"fmt"
    	"runtime"
    	"time"
    )
    
    func main() {
    	for i := 0; i < runtime.NumCPU(); i++ {
    		go func() {
    			for {
    			}
    		}()
    	}
    	for {
    		time.Sleep(100)
    		fmt.Println(time.Now())
    	}
    }
    

    也是打印一会儿之后就卡死了。

    第三个例子

    func main() {
     var count int32 =0
      for i:=0;i<=10;i++  {
      go func() {
       for   {
        atomic.AddInt32(&count,1)
       }
      }()
    
      go func() {
       for   {
        fmt.Println(count==1)
       }
      }()
     }
     time.Sleep(time.Hour)
    }
    

    打印一会儿之后,程序会卡死。
    表面上看 atomic.AddInt32(&count,1)有函数调用,那这里为什么还是卡死了呢。

    =我是分割线====

    因为此"函数调用"非彼"函数调用"。

    思考一个问题:
    Q: 如何判断某个语句是否会导致函数调用呢?
    A: 就是把他们反汇编之后看这些语句是否对应着CALL指令就知道了。

    我们分别看一下fmt.Printlnatomic.AddInt32的反汇编代码就知道了。查看反汇编的指令go tool compile -S main.go

    所以我们可以看到atomic.AddInt32是不会触发函数调用的,fmt.Println会触发函数调用的,进而可以检查自己的抢占flag,决定是否继续执行,还是让出自己。

    感谢go夜读群友的提问和讨论,使得我可以更深入理解抢占式调度的含义。PS.这个问题是我解决的,哈哈哈。

  • 相关阅读:
    STL源码剖析之_allocate函数
    PAT 1018. Public Bike Management
    PAT 1016. Phone Bills
    PAT 1012. The Best Rank
    PAT 1014. Waiting in Line
    PAT 1026. Table Tennis
    PAT 1017. Queueing at Bank
    STL源码剖析之list的sort函数实现
    吃到鸡蛋好吃,看看是哪只母鸡下的蛋:好用的Sqlite3
    cJSON
  • 原文地址:https://www.cnblogs.com/yudidi/p/12443735.html
Copyright © 2011-2022 走看看