协程: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()
}