go语言线程切换 go语言线程模型

golang的线程模型——GMP模型

1、GMP模型是goalng特有的。P与M一般是一一对应的。P(上下文)管理着一组G(goroutine)挂载在M(内核线程)上运行,图中左边蓝色为正在执行状态的goroutine,右边为待执行状态的goroutiine队列。

成都创新互联公司成立于2013年,我们提供高端成都网站建设成都网站制作成都网站设计、网站定制、全网整合营销推广小程序制作、微信公众号开发、成都网站营销服务,提供专业营销思路、内容策划、视觉设计、程序开发来完成项目落地,为成都混凝土泵车企业提供源源不断的流量和订单咨询。

2、我们通过 go func()来创建一个goroutine;有两个存储G的队列,一个是局部调度器P的本地队列、一个是全局G队列。

3、Golang程序启动时申请一大块内存并划分成spans、bitmap、arena区域 arena区域按页划分成一个个小块。span管理一个或多个页。mcentral管理多个span供线程申请使用 mcache作为线程私有资源,资源来源于mcentral。

golang协程调度模式解密

为此Go调度器提供了工作量窃取策略,当某个处理器P没有需要调度的协程时,将从其他处理中偷取协程,每次偷取一半。抢占式调度,是指避免某个协程长时间执行,而阻碍其他协程被调度的机制。

Go语言运行时,通过核心元素G,M,P 和 自己的调度器,实现了自己的并发线程模型。调度器通过对G,M,P的调度实现了两级线程模型中操作系统内核之外的调度任务。

参考:Goroutine并发调度模型深度解析&手撸一个协程池 Golang 的 goroutine 是如何实现的?Golang - 调度剖析【第二部分】OS线程初始栈为2MB。Go语言中,每个goroutine采用动态扩容方式,初始2KB,按需增长,最大1G。

当goroutine被阻塞在channel上时,当前的goroutine就会被挂起,即处于等待模式将不会推入任何goroutines队列中。

调度器为什么要维护多个上下文P 呢? 因为当一个物理线程 M 被阻塞时,P 可以转而投奔另一个OS线程 M (即 P 带着 G 连茎拔起,去另一个 M 节点下运行)。这是 Golang调度器厉害的地方,也是高并发能力的保障。

golang多线程简单逻辑

1、线程:多线程是为了解决CPU利用率的问题,线程则是为了减少上下文切换时的开销,进程和线程在Linux中没有本质区别,最大的不同就是进程有自己独立的内存空间,而线程是共享内存空间。

2、多个用户线程对应一个内核线程,当内核线程对应的一个用户线程被阻塞挂起时候,其他用户线程也阻塞不能执行了。

3、Golang中也实现了内存分配器,原理与tcmalloc类似,简单的说就是维护一块大的全局内存,每个线程(Golang中为P)维护一块小的私有内存,私有内存不足再从全局申请。

4、一般情况下M的个数会略大于P个数,多出来的M将会在G产生系统调用时发挥作用。与线程池类似,Go也提供M池子。

5、调度器 由三方面实体构成:三者对应关系:上图有2个 物理线程 M,每一个 M 都拥有一个上下文(P),每一个也都有一个正在运行的goroutine(G)。


当前标题:go语言线程切换 go语言线程模型
当前链接:http://ybzwz.com/article/dchdhgc.html