版权属于:
桑帅东的博客
作品采用:
《
署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)
》许可协议授权
1. 协程由来
进程
通常表示计算机中正在运行的程序实例。
线程
通常表示内核级的线程。计算机中最小可执行单元
协程
线程分为内核级线程和用户级线程,一个或多个用户级线程要绑定一个内核级线程,其中内核级线程依然叫线程(thread),而用户级线程叫协程(co-routine)。
协程跟线程是有区别的,线程由 CPU 调度是抢占式的,协程由用户态调度是协作式的,一个协程让出 CPU 后,才执行下一个协程,在go语言中,协程叫做goroutine,一个goroutine初始只占几KB,但实际是可伸缩的,如果需要更多内容,runtime 会自动为 goroutine 分配,因此调度起来非常方便,支持大量的goroutine
2. 什么是GMP模型?
GMP模型是Go语言并发模型的核心,它由三个主要组件组成:
3. GMP模型的工作原理
下面通过一个简单的代码示例来演示GMP模型的工作原理。
package main
import (
"fmt"
"runtime"
"sync"
"time"
)
func main() {
// 设置使用的CPU核心数
runtime.GOMAXPROCS(2)
var wg sync.WaitGroup
// 创建10个Goroutine
for i := 0; i < 10; i++ {
wg.Add(1)
go func(id int) {
defer wg.Done()
fmt.Printf("Goroutine %d started\n", id)
time.Sleep(time.Second) // 模拟耗时操作
fmt.Printf("Goroutine %d finished\n", id)
}(i)
}
// 等待所有Goroutine完成
wg.Wait()
fmt.Println("All Goroutines finished")
}
代码解析
P的数量和M的数量的确定
P的数量:由启动时环境变量GOMAXPROCS来决定的,一般设置GOMAXPROCS也不会超过系统的核数
M的数量:go程序启动时,会设置M的最大数量,默认10000。但是内核很难创建出如此多的线程,因此默认情况下M的最大数量取决于内核
评论