goroutine 是 Go 语言支持并发的核心,一个goroutine会以一个很小的栈开始其生命周期,一般只需要2KB。区别于操作系统线程由系统内核进行调度, goroutine 是由Go运行时(runtime)负责调度。例如Go运行时会智能地将 m个goroutine 合理地分配给n个操作系统线程,实现类似m:n的调度机制,不再需要Go开发者自行在代码层面维护一个线程池。
goroutine 好处:占用内存小,大约2KB,资源调度开销少,用户级线程。
启动goroutine
go关键字
go test()
?如果只使用go 开启一个协程,如果主进程执行完毕,协程还没有执行完,这时候协程也会关闭。
为了避免这种情况,使用sync.waitGroup来等待协程完成。下面是代码例子:
package main
import (
"fmt"
"sync"
"time"
)
var wg sync.WaitGroup
func test() {
for i := 0; i < 10; i++ {
fmt.Println("test golang", i)
time.Sleep(time.Millisecond * 100)
}
wg.Done() //协程计数器-1
}
func main() {
wg.Add(1) //协程计数器+1
go test() //开启一个协程
for i := 0; i < 10; i++ {
fmt.Println("main golang", i)
time.Sleep(time.Millisecond * 20)
}
wg.Wait() //等待协程执行完毕
fmt.Println("主线程完成")
}
通过下面代码,发现每次打印的数字都不一样这是因为 10 个 goroutine是并发执行的,而 goroutine 的调度是随机的。
package main
import (
"fmt"
"sync"
)
var wg sync.WaitGroup
func main() {
for i := 0; i < 10; i++ {
wg.Add(1)
go test(i)
}
wg.Wait()
}
func test(i int) {
defer wg.Done()
fmt.Println("你好test", i)
}
3、设置golang并行运行时占用的cpu数量
Go 语言中可以通过 runtime.GOMAXPROCS()函数设置当前程序并发时占用的 CPU 逻辑核心
数。