写点什么

Go 学习笔记之 Goroutines

发布于: 2 小时前
Go 学习笔记之 Goroutines

1、goroutine 是什么?

在 Go 语言中,每一个并发的执行单元叫作一个 goroutine,它是 Go 里的一种轻量级线程——协程。


当一个程序启动时,其主函数即在一个单独的 goroutine 中运行,我们叫它 main goroutine。新的 goroutine 会用 go 语句来创建。在语法上,go 语句是一个普通的函数或方法调用前加上关键字 go。go 语句会使其语句中的函数在一个新创建的 goroutine 中运行。而 go 语句本身会迅速地完成。

f()    // call f(); wait for it to returngo f() // create a new goroutine that calls f(); don't wait
复制代码


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 中,等待被调度。


发布于: 2 小时前阅读数: 4
用户头像

坚持分享接地气儿的架构技术文章! 2018.02.26 加入

同名微信公众号「架构精进之路」,专注软件架构研究,技术学习与职业成长!坚持原创总结、沉淀和分享,希望能带给大家一些引导和启发,感谢各位的支持(关注、点赞、分享)!

评论

发布
暂无评论
Go 学习笔记之 Goroutines