Go 学习笔记之 Goroutines
1、goroutine 是什么?
在 Go 语言中,每一个并发的执行单元叫作一个 goroutine,它是 Go 里的一种轻量级线程——协程。
当一个程序启动时,其主函数即在一个单独的 goroutine 中运行,我们叫它 main goroutine。新的 goroutine 会用 go 语句来创建。在语法上,go 语句是一个普通的函数或方法调用前加上关键字 go。go 语句会使其语句中的函数在一个新创建的 goroutine 中运行。而 go 语句本身会迅速地完成。
2、并发
2.1 什么是并发?
并发:两个或两个以上的任务在一段时间内被执行。
我们并不关心这些任务是否在同一时刻执行,我们只是知道,这些任务在这一段时间能能够都被执行,当然这一段时间可以很长,也可以很短。
2.2 并发的最小并发单位是什么?
进程是计算机资源分配最小的单位,是 CPU 分配资源的基本单位,具有独立的内存。
线程是计算机调度最小的单位,也是程序执行的最小单位,是在进程中的,一个进程往往会有一个到多个线程。
2.3 计算机是如何实现并发的?
计算机的分时调用是并发的根本,CPU 通过快速的切换作业来执行不同的作业,基本的调度单位在执行的时候可以被阻塞掉,此时就会将 CPU 资源让出来,等到该调度单位再次被唤醒的时候,又可以使用 CPU 资源,而操作系统保证了整个的调度过程。
3、Goroutine 的调度策略
Go 的调度器内部有三个重要的结构:M,P,S
M:代表真正的内核 OS 线程,和 POSIX 里的 thread 差不多,真正干活的人
G:代表一个 goroutine,它有自己的栈,instruction pointer 和其他信息(正在等待的 channel 等等),用于调度。
P:代表调度的上下文,可以把它看做一个局部的调度器,使 go 代码在一个线程上跑,它是实现从 N:1 到 N:M 映射的关键。
一个 M 会关联两个东西,一个是内核线程,一个是可执行的进程。
一个上下文 P 会有两类 Goroutine,一类是正在运行的,图中的蓝色 G;一类是正在排队的,图中灰色 G,这个会存储在该进程中的 runqueue 里面。
这里的上下文 P 的数量也表示的是 Goroutinue 运行的数量,一般设置为几个,机器中就会并发运行几个。当然这里 P 的数量是可以设置的,通过环境变量 GOMAXPROCS 的值,或者通过运行时调用函数 runtime.GOMAXPROCS()进行设置,最大值是 256。
4、goroutine 唤醒之后,需要做什么?
goroutine 处于 waiting 状态的话,在调用 runtime·ready 函数之后,会被唤醒,唤醒的 goroutine 会被重新放到,M 对应的上下文所对应的 runqueue 中,等待被调度。
版权声明: 本文为 InfoQ 作者【架构精进之路】的原创文章。
原文链接:【http://xie.infoq.cn/article/cfbd28ded786ba57fb6ca185d】。文章转载请联系作者。
评论