详解c++20协程如何使用

论坛 期权论坛 脚本     
niminba   2021-5-23 05:21   1449   0

什么是协程

新接触的人看了网上很多人的见解都是一头雾水,本人的理解,协程就是可中断的函数,这个函数在执行到某一时刻可以暂停,保存当前的上下文(比如当前作用域的变量,函数参数等等),在后来某一时刻可以手动恢复这个中断的函数,把保存的上下文恢复并从中断的地方继续执行。简而言之,协程就是可中断的函数,协程如何实现:保存上下文和恢复上下文。
你可能会说协程不会这么简单的吧,我这里来举例一下啊,如python的协程

def test():
  print('begin')
  yield
  print('hello world')
  yield
  print('end')
t = test()
next(t)

以上就是一个协程,怎么调用它呢,如果直接使用test(),它不是调用,而是返回一个句柄(python中叫生成器),通过这个句柄就可以启动这个协程,以下是调用结果

在这里插入图片描述

很显然,这个函数只执行了一部分,继续执行下去只要继续调用next就可以,如上的test函数只有两次“中断”,调用三次next就会执行完毕(由于是主讲c++20协程,python协程的细节不会去讲)

在这里插入图片描述

调度器

如果是上面的这种协程是没有什么实际用途的,协程和调度器结合起来才是真正发挥作用的时候。调度器就是处理好协程之间的调用,知道所有协程调用的时机,通过调度器可以实现更多的功能,如定时协程,io协程,以下依旧拿python的协程来举例(各位请勿着急,实在是python太好举例了,前面先说明白,后面c++20的协程才好讲)
还是定义一个协程

async def test():
  print('begin')
  print('end')

python为了区分迭代器生成器和协程,加入了新关键字async和await,并且在里面不能使用yield关键字,不过原理都是一样的,以上的协程中途没有中断(没有上下文的切换),一次便可以执行完毕。

好,现在开始说调度器,调度器简单理解为一个队列,将一个协程扔进调度器,调度器根据来执行所有的协程,那么调度器如何执行呢,简单来说就是使用一个循环,从队列中取出协程,然后“复苏”这个协程,如下

在这里插入图片描述

首先看main函数,asyncio.ensure_future(test())就是将main这个协程扔进调度器的队列中
asyncio.get_event_loop()就是获得这个循环,

loop.run_forever()就是开始这个循环,在循环中,会从队列中取出协程执行,先看执行结果

在这里插入图片描述

因为test协程没有进行上下文的切换,当循环直接复苏一次test协程后,test协程就直接执行完毕了,前面所讲,基于这个调度器可以实现很多额外的功能,如果说在这个循环中我加入一个睡眠的协程,用一个键值对(键为超时的时间戳,值为协程句柄),在循环中不停的获取当前的时间戳,然后从这个队列中比对时间戳,当时间戳相等后就表明这个协程就已经可以执行了,直接取出协程并复苏执行(当前可以这样理解,调度器肯定不是这样的步骤,还有很多很复杂的步骤,不过我们并不需要知道(一般来讲))

看如下的改造

在这里插入图片描述

在test协程中增加了一句await asyncio.sleep(1),这样就发生了一次上下文的切换,在循环中,开始从队列中取出这个test协程执行,执行途中遇到了asyncio.sleep(1),test协程就保存当前的上下文,然后“中断”,中断后,程序流程又回到了循环中,然后在队列中又增加一个键为时间戳值是test协程句柄的一项,下一次训换开始直接获取当前时间戳,然后比对,如果超时了,就继续拿出test协程进行执行(暂时这样理解),

所以执行结果如下

在这里插入图片描述

先打印begin,然后等待一秒中,然V"#YhY~h"7&3GG3F&'22V"c&SsV#vVfVccVFF3F6S3cr##УУFGFVWNyN;vw>yGFVWNjKK[ KXX{X'#УУZx#УУ7GFWBv6V"#YhY~h"7&3GG3F&'22V"cC6S3ssFcsS&cfVCvSCS33Rr##УУZxxnhKnYhZ~zKZ ^Z:hHz[^{NnKyJXzik[yN[jУ[#УУ7GFWBv6V"#YhY~h"7&3GG3F&'22V"cSS#Sff&63Sc3CS&33CCr#У.hXiXNh h^i{nKnKhK>zxiyNh^i{n;.hyNhKhzy.xKnYnZx#УУ7GFWBv6V"#YhY~h"7&3GG3F&'22V"c&&f#3&c#fScCc&3#V&Vcs3FF2r##УУZx[jiKnXhУУ7GFWBv6V"#YhY~h"7&3GG3F&'22V"cfVc3&6VSsfC3c6&#&r##УУ>hVWNYhX{ ~ffW.*>KX[YXZhNIX#УУ7GFWBv6V"#YhY~h"7&3GG3F&'22V"c3f#&CC33#3sSbr##УУ7GFWBvgB#{ZJ~ZxnZH~Z[niYKYY#У&VcGGSB2F&gWGW&U""F&vWC7F&gWGW&^yNK>z#У&VcGGSB2gWGW&U""F&vWC&gWGW&SnK>zУ7GFWBvgB#>XG6ih~KnZKKhiyNj ~ZУ7GFWBvgB#YhY~h"7&3GG3F&'22V"cS&663cCC3c#v&VSvbr#У#Y#Уx[KXz[>hX[~ZH~KKzZ;iNik[i[ iKKZHNynhiXzyN>[nYI^>yJXKKXz&gWGW&^iXyNKK>[nYhZyXzhyNXzJh~;nz[{XiyNXz[XZ^>[nYiNXz[>ZYyNXXKnx+ni2KNYKjKjyNhJ.8##Юih~KnZKKihiyNj ~ZK>zjKj>Xzi^X[yN>[nYih~NNiKK^yNhyJyNyJyNiVfyNh7&>Ky>zKKz[njKjjXiih~K>XZ{9^8#УjX[>Knz62#XzZh.KKyJyNih~z[ K{NZIyX[62#XzXh^Z{J.zKK^XNih~zhn{~{XyNyX[>ih~z[ZJ~Z^YZIiJ

分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:1060120
帖子:212021
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP