GO的协程调度模型

一、常见的多线程模型

1、用户级线程模型
此时,用户线程和KSE(可以认为是内核线程)是M:1的关系,这m个用户级线程“共享”(对应)同一个内核线程,所以这m个用户级线程必须要互斥使用这1个内核线程,所以需要用户自己来管理调度这m个用户线程
在这里插入图片描述
2、内核级线程模型
此时用户线程和内核线程是1:1的关系,此时用户线程间的调度均可以交由内核来管理
在这里插入图片描述
两级线程模型
用户线程和内核线程是m:n也就是多对多的关系,一个用户线程可以对应多个内核线程,1个内核线程也可以对应多个用户线程。此时用户线程需由用户自己来管理,内核线程由内核来进行管理。go的协程调度模型MPG就是一种特殊的两级线程模型
在这里插入图片描述
go的协程调度模型MPG
在这里插入图片描述

二、传统线程模型

普通的线程并发模型,就是像Java、C++、或者Python,线程间通信都是通过共享内存的方式来进行的。非常典型的方式就是,在访问共享数据(例如数组、Map、或者某个结构体或对象)的时候,通过锁来访问这些数据结构,然后基于里面的数据块,并发执行相关操作。因此,在很多时候,衍生出一种方便操作的数据结构,叫做“线程安全的数据结构”。例如Java提供的包”java.util.concurrent”中的数据结构。Go的sync包也提供了对传统的线程并发模型的支持,但Go本身更推崇CSP(communicating sequential processes)的并发模型(在go中CSP并发模型的实现叫MPG模型),通过goroutine和channel来组合实现

  • goroutine 是Go语言中并发的执行单位。即为go中的一个协程
  • channel是Go语言中各个并发执行单位(goroutine)之间的通信机制。 通俗的讲,就是各个goroutine之间通信的”管道“,类似于Linux中的pipe管道

三、go中的协程调度模型 MPG

简单来说,go的协程调度模型为:

在这里插入图片描述
在这里插入图片描述

  • M指的是Machine,即工作线程,一个M直接关联了一个内核线程(KSE:内核调度实体),可以直接理解为M就是内核线程。M的数量m表示在程序执行的任意时刻底层最多有m个内核线程来执行我们的goroutine(也就是go语句)
  • P指的是processor,即逻辑处理器,表示M所需的上下文环境(或运行资源)。每个P维护一个p_Local任务队列(本地任务队列),由启动时环境变量 $GOMAXPROCS 或者是由runtime.GOMAXPROCS()决定,注意GOMAXPROCS的值不会影响M的数量。P的数量决定了程序的并行度,这意味着在程序执行的任意时刻,最多都只有$GOMAXPROCS个goroutine在同时运行!!!。
  • G指的是Goroutine,其内部不仅封装了我们用Go实现的协程(即用go关键字修饰的方法),还用于协程进行上下文切换时保存该协程的硬件上下文(相关栈信息,比如pc,sp(堆栈寄存器)等)

当一段go代码(被go关键字修饰的代码)想要运行时,其必须先与一个G相绑定,然后这个G想要运行,必须与一个逻辑处理器P和一个工作线程M相绑定。

G

  • goroutine:go中的协程也可以认为是一种受管理的轻量线程,goroutine使用go关键词创建(即为go语句)。
  • G的内部不仅封装了我们用Go实现的协程(即用go关键字修饰的方法),还用于协程进行上下文切换时保存该协程的硬件上下文(相关栈信息,比如pc,sp(堆栈寄存器)等)
    【注意】:
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值