一文看懂Go语言协程的设计与原理

本文深入探讨了Go语言协程的历史演变,从单进程到多进程、多线程,再到协程时代。Go语言的G-M模型和G-P-M模型详细解析了协程的调度机制,包括工作窃取和抢占策略。文章总结了P在GPM模型中的作用,强调了goroutine在解决线程开销问题上的优势,并提及其他语言的协程实现。
摘要由CSDN通过智能技术生成

首发于微信公众号:【码农在新加坡】,欢迎关注。

个人博客网站:一文看懂Go语言协程的设计与原理

背景

Go语言最大的特色就是从语言层面支持并发(Goroutine),Goroutine是Go中最基本的执行单元。事实上每一个Go程序至少有一个Goroutine:main Goroutine。Go 程序从 main 包的 main() 函数开始,在程序启动时,Go 程序就会为 main() 函数创建一个默认的 goroutine。

为了了解Go语言协程的设计,我们从历史设计出发,来看看最终Goroutine怎么一步一步到现在的设计的。

单进程时代

早期的操作系统每个程序就是一个进程,操作系统在一段时间只能运行一个进程,直到这个进程运行完,才能运行下一个进程,这个时期可以成为单进程时代——串行时代。

如图:进程之间串行执行,A、B、C 三个进程按顺序执行。

在这里插入图片描述

单进程时代的两个问题:

  1. 单一执行流程、计算机只能一个任务一个任务的处理。
  2. 进程阻塞所带来的CPU浪费时间是不可避免的(如进程A阻塞了,然后CPU是单进程没有任何的切换能力,但是需要等待进程A结束后才能执行下个进程)

遇到这种问题,我们怎么才能充分利用CPU呢?

多进程时代

后来操作系统就具有了最早的并发能力:多进程并发,当一个进程阻塞的时候,切换到另外等待执行的进程,这样就能尽量把CPU利用起来,CPU就不浪费了。

在多进程时代,有了时间片的概念,进程按照调度算法分时间片在 CPU 上执行,A、B、C 三个进程按照时间片并发执行。(调度算法)
在这里插入图片描述

这样做有两个优点:

  1. 对于单个核可以并发执行多个进程,应用场景更加丰富,
  2. 当某个进程 IO 阻塞时,也能保证 CPU 的利用率。

但是随着时代的发展,CPU 通过进程来进行调度的缺点也越发的明显。

进程切换需要:

  1. 切换页目录以使用新的地址空间
  2. 切换内核栈和硬件上下文

因为进程拥有太多资源,在创建、切换和销毁的时

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值