关于go协程的调度和执行顺序

无论是java还是go,开启线程和协程的时候,执行的顺序都是一样的。

例子1:

 

func funcB() {

    println("funcB")

}

func funcA() {

    println("funcA")

}

 

func main() {

funcA()

    go funcB()

    select {}

}

 

实际的执行顺序还是顺序执行FuncA(),再Go FuncB().输出为

funcA

funcB

 

例子2:

 

func funcB() {

    println("funcB")

}

func funcA() {

    println("funcA")

}

 

func main() {

   go funcB()

funcA()

   select {}

}

 

实际的执行顺序是开启FuncB()协程,然后继续往下执行funcA()为什么输出还是funcA和funcB

funcA

funcB

因为当开启协程的那一刹那(还没执行打印B),主协程和funcB的协程就开启了资源竞争,所以在下一个执行分片,可能已经是执行funcA()里的打印A了,然后select{}阻塞,funcB协程获得执行分片,打印funcB。

 

 

例子3:

打印1000个funcD的时候,在打印某一个funcD的时候就开始调度输出执行go funcB2的内容了。

 

例子4:

这个例子表明,在没有go之前的语句,都是顺序执行的(打印100次A),不会调度go的子协程。因为那时候还没开启子协程。

开启子协程后,什么时候能获得优先权去运行是不固定的,根据系统调度来决定的。

子协程要获得调度执行,有三种情况:

  1. 主协程还没执行完毕的时候,与主协程竞争
  2. 主协程所有内容已经执行完毕
  3. 主协程主动阻塞。比如chan的操作或者主动Sleep

猜你喜欢

转载自blog.csdn.net/kojhliang/article/details/82461328