协程:coroutine
轻量级“线程“
编译器/解释器/虚拟机层面的多任务
多个协程可能在一个或多个线程上运行
在调用一个方法的前面加上 go 就是 goroutine 它会让方法异步执行,相当于协程
package main
import (
    "fmt"
    "time"
)
func main() {
    go Run()
    time.Sleep(1 * time.Second)
}
func Run() {
    fmt.Println("我跑起来了")
}
非抢占式多任务处理,由协程主动交出控制权
package main
import (
    "fmt"
    "time"
)
func main() {
    var a [10]int
    for i := 0; i < 10; i++ {
       go func(i int) {
          for {
             a[i]++
          }
       }(i)
    }
    time.Sleep(time.Millisecond)
    fmt.Println(a)
}子程序是协程的一个特例

go 语言中的协程:goroutine
任何函数只需加上 go 就能送给调度器运行
不需要在定义时区分是否是异步函数
调度器在合适的点进行切换
使用-race来检测数据访问冲突

goroutine 可能的切换点
I/O, select
channel
等待锁
函数调用(有时)
runtime.Gosched()
只是参考,不能保证切换,不能保证在其他地方不切换
协程管理
package main
import (
    "fmt"
    "sync"
)
func main() {
    var wg sync.WaitGroup
    wg.Add(1)
    go Run(&wg)
    wg.Wait()
}
func Run(wg *sync.WaitGroup) {
    fmt.Println("我跑起来了")
    wg.Done()
}
                        Go 第12章 goroutine