协程的简单介绍

协程的诞生史:

1958 年,Melvin Conway 创造了协程(Coroutine)一词。

1963 年,协程这一概念正式发布于论文 Design of a Separable Transition-Diagram Compiler 中。所以协程这一概念诞生于1963年,可以说非常早,相比之下,线程的概念也是1966年才提出的。

在这篇论文中,Conway 提出将 COBOL 编译过程中的词法分析和语法分析结合起来完成,而不是将二者看成是完全独立的步骤。词法分析和语法分析分别有自己的控制流,在 Conway 的方法里,这两个控制流可以保存自己运行的上下文并移交执行权给对方,并在合适的时候恢复自己的上下文并继续执行。这种概念就叫做协程。

协程的概念:

在后来的发展中,协程的概念发生了一些改变,直到现在,协程有且仅有唯一定义:能够暂停和恢复(yield and resume)的函数。

当然可能有些人可能没有接触过协程,我会讲一个小故事去诠释它的思想:

在很久之前,咱们的电脑CPU虽然都是单核的,意味着同时只能运行一个进程, 但是事实上我们可以一边放歌,一边玩游戏,从宏观上是并行执行的,这是怎么实现的呢?如下图所示,我们把CPU抽象成一条时间线,并把它分成时间片0,1,2,3,4,..... , 现在有三个进程,每个进程在相应的时间片开始执行,比如在0号时间片结束后就到1号时间片了,进程1应该把CPU让给进程2,在切换到进程2之前,会把进程1执行的上下文从CPU寄存器保存到进程1的PCB中,然后在把进程2PCB中的上下文加载到CPU寄存器中, 此时进程1就暂停了(让出CPU又叫yield),进程2就获取了CPU(恢复又叫 resume)

通过单核 switch processes 的概述,我们大致也可以猜测到什么东东,是的,如你所想,协程也是这么回事儿,不过进程的暂停和恢复是由内核做的,协程的暂停和恢复需要由我们自己来掌握,如下图所示:

协程存在的意义

一种非抢占式的多任务并发的调度思想:协作式调度。每个任务执行完毕之后才将 CPU 的使用权转移给另一个任务,没有优先级和抢占,十分和谐。

协程与线程,进程的关系

根据下图看协程,线程,进程的对应关系,不做过多解释

线程上下文切换的成本在几十纳秒到几微秒间,当线程繁忙且数量众多时,这些切换会消耗绝大部分的CPU运算能力。

协程的分类

  1. 有栈协程:有自己的函数栈(C_libco Go_coroutine)
  2. 无栈协程:使用当前进程或者线程的调用栈 (C+20_coroutine)
  3. 对称协程:任何一个协程都是相互独立且平等的,调度权可以在任意协程之间转移,例如go语言的协程就是对称线程 (Go_coroutine)
  4. 非对称协程:协程出让调度权的目标只能是它的调用者,即协程之间存在调用和被调用关系,例如libco提供的协议就是非对称协程(C_libco C+20_coroutine)

1、有栈协程和无栈协程

(1)如果每个协程都有自己的调用栈,类似于线程的调用栈就是有栈协程,微信的libco、Golang中的 goroutine、Lua中的协程都是有栈协程。
实现方式:在内存中给每个协程开辟一个栈内存,当协程挂起时会将它的运行时上下文(即栈空间)从系统栈中保存至其所分配的栈内存中,当协程恢复时会将其运行时上下文从栈内存中恢复至系统栈中;

采用有栈协程有优点也有缺点,优点是可以任意嵌套,只要保留了当前栈的信息,可以任意的切换到其他协程中,而缺点则是性能有一定的损失,在保留栈空间信息的拷入拷出都会影响性能,同时栈的扩大和缩小需要实现动态,这里会导致内存浪费;
(2)与有栈协程相反,无栈协程不会为各个协程开辟相应的调用栈。无栈协程通常是基于状态机或闭包来实现。使用无栈协程不需要修改调用栈,也无需额外的内存来保存调用栈,因此它的开销会更小,同时无需要考虑栈需要动态扩大缩小的问题,但是相比于保存运行时上下文这种实现方式,无栈协程最大的问题它无法实现在任意函数调用层级的位置进行挂起

(3)有栈协程和无栈协程总结如下:

  • 内存资源使用:无栈协程借助函数的栈帧来存储一些寄存器状态,可以调用递归函数,而有栈协程会要申请一个内存栈用来存储寄存器信息,调用递归函数可能会爆栈;
  • 速度:无栈协程的上下文比较少,所以能够进行更快的用户态上下文切换;
  • 功能性:有栈协程能够在嵌套的协程中进行挂起/恢复,而无栈协程只能对顶层的协程进行挂起,被调用方是不能挂起的;

2.对称协程和非对称协程:N\A 写的很明了了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值