Go 1.14之前的一个死循环例子

第一个例子

package main

import (
    "runtime"
    "time"
)

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

不会打印OK

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

为什么不会打印?

golang高并发模型

第二个例子

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.这个问题是我解决的,哈哈哈。

猜你喜欢

转载自www.cnblogs.com/yudidi/p/12443735.html