go语言不但有着独特的并发编程模型,以及用户级线程goroutine,还拥有强大的用于调度goroutine、对接系统线程的调度器。
这个调度器是go语言运行时系统的重要组成部分,它主要负责统筹调配go并发编程模型中的三个元素,即:G(gotoutine的缩写),P(process的缩写)和M(machine的缩写)。
其中M指代的是系统级线程。而P指的是一种可以承诺若干个G,而且能够使这些G适时地与M进行对接,并得到真正运行的中介。
demo:

package main
import (
    "fmt"
    //"time"
)
func main() {
    num := 10
    sign := make(chan struct{}, num)
    for i := 0; i < num; i++ {
        go func() {
            fmt.Println(i)
            sign <- struct{}{}
        }()
    }
    // 办法1。
    //time.Sleep(time.Millisecond * 500)

    // 办法2。
    for j := 0; j < num; j++ {
        <-sign
    }
}

golang让多个goroutine按照既定的顺序运行
demo:

package main
import (
    "fmt"
    "sync/atomic"
    "time"
)
func main() {
    var count uint32
    trigger := func(i uint32, fn func()) {
        for {
            if n := atomic.LoadUint32(&count); n == i {
                fn()
                atomic.AddUint32(&count, 1) //count++
                break
            }
            time.Sleep(time.Nanosecond)
        }
    }

    for i := uint32(0); i < 10; i++ {
        go func(i uint32) {
            fn := func() {
                fmt.Println(i)
            }
            trigger(i, fn)
        }(i)
    }
    trigger(10, func() {})
}