GoLang之协程是怎样的存在

GoLang之[协程第一话]协程是怎样的存在

1.为什么说协程是“用户态线程”?

我们已经知道线程是进程中的执行体,拥有一个执行入口、已经从进程虚拟地址空间中分配的栈,包括用户栈和内核栈
操作系统会记录现场控制信息。而线程获得cpu时间片以后才可以执行。Cpu,这里栈指针、指令指针等寄存器都要切换到对应的线程。

image-20220919201353799

如果线程自己又创建几个执行体,给他们各自指定执行入口。申请一些内存分配给他们用作执行栈,那么线程就可以按需调度这几个执行体了。为了实现这些执行体的切换,现场也需要记录他们的控制信息,包括ID、栈的位置、执行入口、地址、执行现场等等。

image-20220920092210036

线程可以选择一个执行体来执行,此时cpu中指令指针就会指向这个执行体的执行入口,栈基和栈指针寄存器也会指向线程给他分配的执行栈。

image-20220920092343581

要切换执行体时,需要先保存当前执行的执行现场。然后切换到另一个执行体。

image-20220920092419014

通过同样的方式可以恢复到之前的执行体,这样就可以从上次中断的地方继续执行。这些由线程创建的执行体就是所谓的携程。因为用户程序不能操作内核空间,所以只能给协程分配用户栈。
操作系统对协程一无所知,所以协程又被称为用户态线程。

image-20220920092550714

协程的思想很早就被提出来了,最初是为了解决编译器实现中的问题,后来相继出现了很多种实现方式,例如Windows中的纤程,再例如lua中的coroutine。

image-20220920092606815

2.协程如何实现“主动让出”和“恢复”?

可无论被赋予什么样的名字,有着怎样的用法,在创建协程时都要指定执行入口,底层都会分配协程执行栈和控制信息,否则又该如何实现用户态调度呢?而让出执行权时,也都要保存执行现场,不然如何能够从中断处恢复执行?所以,协程思想的关键在于控制流的动让出“和”恢复“

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hB14qxrg-1663644691629)(C:/Users/86158/AppData/Roaming/Typora/typora-user-images/image-20220920092921664.png)]

每个协程拥有自己的执行栈,可以保存自己的执行现场,所以可以由用户程序按需创建携程,携程主动让出执行权时,会保存执行现场,然后切换到其他协程。协程恢复执行时,会根据之前保存的执行现场,恢复到中断前的状态继续执行。这样就通过协程实现了轻量又灵活的由用户态进行调度的多任务模型。

image-20220920093207370

即便如此,协程依然风平浪静很多年。直到高并发成为主流趋势,瞬间抵达的海量请求,让多进程模型下内存资源捉襟见肘

image-20220920093235206

让多线程模型下,内核(态)用户(态)两头忙,却依然疲于应对,协程这种灵活轻量的用户太调度模型便受到了广泛的关注,而真正让协程大放异彩的,是他在io多路复用中的应用。二者的结合,助力协程成为炙手可热的高并发解决方案

image-20220920093339916

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值