深入解析Go语言(三)--goroutine - Go语言中文社区

深入解析Go语言(三)--goroutine


很多人都是冲着GO的高并发来学习Go的,今天我们来解析一下

首先我们先明确两个概念:并发和并行

并发:一个CPU能同时执行多项任务,在很短的时间内,CPU来回切换执行任务,宏观上是同时的,微观上其实还是顺序执行,因为时间差太小,所以看起来就是多个任务同时执行,这就是并发

并行:当系统有多个cpu时,每个cpu同一时刻都运行任务,互不抢占自己所在的资源,同时进行,这就是并行

明确一下:并行不是并发,并行是可以同时做很多事情,并发是可以同时管理很多事情。

我们先介绍一下并发的过程:

创建一个go==>放在全局运行队列中=调度器进行调度分给=>逻辑处理器==>放在本地运行队列中=等待=》执行(逻辑处理器执行)

接下来我们把每个过程都详细说明一下

groutine能拥有强大的并发实现是通过GPM调度模型实现,下面就来解释下goroutine的调度模型。

Go的调度模型:GPM调度模型

Go的调度器内部有四个重要的结构:M,P,S,Sched,如上图所示(Sched未给出)

M:M代表内核级线程,一个M就是一个线程,goroutine就是跑在M之上的;M是一个很大的结构,里面维护小对象内存cache(mcache)、当前执行的goroutine、随机数发生器等等非常多的信息
G:代表一个goroutine,它有自己的栈,instruction pointer和其他信息(正在等待的channel等等),用于调度。
P:P全称是Processor,处理器,它的主要用途就是用来执行goroutine的,所以它也维护了一个goroutine队列,里面存储了所有需要它来执行的goroutine

Sched:代表调度器,它维护有存储M和G的队列以及调度器的一些状态信息等。

定义都了解了,让我们看一下调度的实现

形象化的话,就是上面这种过程,上图中是有两个M,也就是有两个线程,每一个M中存在一个处理器(p),p下面的G是正在执行的协程(goroutine),右面连得的就是本地运行队列,里面就是等待执行的协程,当正在执行的G完成之后,P就会调用队列中的G(队首),所以p就是维护这个队列的或者说是控制。

有人可能会问队列中的G从哪里来的,这就是上面没有体现出来的Sched(调度器),因为他储存着这些信息,所以他会根据不同情况给每个逻辑处理器分配goroutine,而p只需要维护自己的本地运行队列就可以。

 

从上面我们还可以得出一个结论就是,Go也可以实现并行,通过创建多个逻辑处理器,这样调度器可以同时分配全局队列中的goroutine到不同的逻辑处理器,go如何实现并行呢?

答案很简单就是通过runtime包

runtime.GOMAXPROSS(a int)   //设置CPU核数为a,一个CPU可开启一个线程,不设置默认是1

可以通过runtime.NumCPU()来查看本机的CPU核数,不要盲目设置

以上这些就是go并发的大致过程,欢迎大家评论指正!

版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/LYue123/article/details/86598374
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
  • 发表于 2020-03-01 20:57:00
  • 阅读 ( 1272 )
  • 分类:Go

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢