有栈协程和无栈协程

一、栈和协程

我们知道,计算机的内存是有限的。虽然抽象出来一层虚拟内存,虽然扩展到了ARM64,但是仍然不代表对内存的使用随心所欲。正如更高层次来看一样,计算机始终是资源的竞争,一旦没有了资源的竞争,或者资源的竞争降低到了可以忍受的地步,那么现有的编程技术甚至包括整个计算机体系,都会有一个革命性的变化。换句话说,资源的竞争,无论是在现实的物质世界,亦或是计算机中的虚拟世界还是计算机的组成的物理体系,都是高度具现化的,至少在可预见的未来是无法解决的。
回到编程体系结构中,为了解决内存资源的竞争,就要对内存进行各种处理,最典型的就是把内存分为栈和堆。什么是栈?什么是堆,这个在前面详细的说明过,在不同的编程语言中可能有细微的不同,但是在操作系统中,栈和堆的定义是非常清晰的。最典型的不同在于,栈是不需要使用者主动管理,而堆需要。所以不需要使用者主动处理的栈,成为了所有进程、线程、协程绕不过去的坎儿。
其实协程的优势在哪儿呢?适用场景呢?一般来说,如果是CPU密集型的程序,那么协程的意义不大。但是对于网络高并发这种IO密集型,协程还是可以大显身手的。那协程相比线程虽然优势不少,但仍然是要考虑协程间操作时,相关的局部变量和调用堆栈的处理。而根据不同的实现方式,可以把堆栈的处理分为两种情况即:有栈协程和无栈协程。
因此也衍生出来对称协程和非对称协程,对称协程是指各协程间是平等的,独立动作;反之,则在协程间有调用关系需要处理。
什么是调用堆栈(callback Stack)?其实就是函数调用过程中对相关的调用地址、参数、返回值等的一种处理机制,它一般都是放到栈空间里,形成一种栈机制。而协程在运行时是有栈空间的,有栈协程是自已有自己的堆栈,无栈协程是指本身不具有堆栈而共用系统堆栈空间。要区分清楚。
更多的相关栈和堆的知识,可以回头看一看操作系统或者计算体系相关的书籍,就门儿清了。

二、有栈协程

有栈协程意味着调用堆栈的保存和恢复,可以使用汇编或者ucontext来实现,表现为包含类似yield/resume(无栈协程仅支持栈顶这个动作,要区别开)之类的动作函数。有栈协程的调用机制,更类似线程的调度,它需要一个压栈和出栈的过程,用来保存和恢复相关上下文(其实主要就是寄存器状态)的操作。这样就可以保证整个协程运行的安全性。
可是,数据的保存和恢复虽然数量不大,又在寄存器上,但仍然不可避免的加大整个系统的开销,特别是协程大数量的情况下,性能的损失是一定的,在这方面,天然是比不过无栈协程的。它的一个例子就是腾讯的libco。

三、无栈协程

无栈协程使用类似Wait这类的动作函数来实现,它类似于一个状态机,比如前面提到的使用switch来实现,这样就保证了整个协程的运行过程,更像在系统栈上的跳跃,而不会有任何的进出栈的开销,自然效率就大很多了。它的一个例子是Python的协程就是一个无栈协程而且是非对称的。RUST的新版本协程库就是无栈的(老的绿色线程是有栈协程)。不过为了实现 async/await ,引入了pin的非安全机制,也不能不说是一个瑕疵。

四、总结

正如一再强调的一样,编程一定会朝着越来越简单化的方向飞奔,除了个别专业高度聚集的地方,大量的框架被原生聚合到编程语言中,导致编程的难易度不断的向下发展,这对整个社会来说一定是件好事,但对于应用的运维来说,未必是。编程世界的思想和现实世界的思想无一不是想通的,明白了,就豁然了。
努力吧,归来的少年!
在这里插入图片描述

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值