C++ 20 协程 Coroutine

C++20 协程

C++ 20有一个新玩意,协程。这玩意对C++的未来可能是重要一环,也会是让C++成为服务器编程有力工具。

对C++20的协程,最简单的理解协程是可以重入的特殊函数。就是这个函数在执行的过程,可以(通过co_await ,或者co_yield)挂起,然后在外部(通过coroutine_handle)恢复运行。

我测试的代码都是在Visual studio 2022上运行的。据说GCC 10.0 也已经支持。

协程是特殊的函数

首先再次强调,C++ 20的协程是一个特殊函数。只是这个函数具有挂起和恢复的能力,可以被挂起(挂起后调用代码继续向后执行),而后可以继续恢复其执行。如下图:

如图所示,协程并没有一次执行完成,可以被反复挂起,挂起后可以恢复到挂起的点继续运行。

C++ 20协程的特点

那我们来看看C++ 20 协程的一些特点和用途。

首先,C++ 20 协程是一个无栈(stackless)的协程。同时,C++ 20 协程是非对称的协程,和Linux传统的Context Switch有区别。更像Windows的纤程。和C#的协程也比较相像,毕竟是微软的提案。

传统的Context Switch是有栈协程,你可以认为Context 协程都是运行在栈上,Context 协程的切换就是切换栈。同时因为其是有栈协程。切换是对称的,都是栈切换。你可以从主线程上切换为另外一个Context 协程栈,也可以从一个Context 协程切换为主线程,也可以Context 协程之间切换。Context 协程的状态也就是保存在栈上。

C++ 20的协程可以用来干啥呢?和大部分协程用途类似,就是异步编程用的。看图1就可以明白,每次一次协程的挂起都可以视为协程进入一个等待状态,比如请求一个网络,需要HTTP get一个文件,然后对文件进行分析。那么就可以用协程来包装整个处理,在发起HTTP请求后,挂起协程(处理其他事情),等待应答或者超时后,再恢复协程的运行。

但不足的是目前C++ 20的协程才是一个开始,说实话,目前的协程只提供基本框架,写起来并不舒服。C++目前在IO方面,特别是网络IO方面还不完善。需要一个大量异步IO库,才能用好C++ 20协程。

如果C++ 20的协程周边更加完整,也许C++又能在服务器编程这块能重新面对Go这类语言的威胁。

C++协程的是三个关键字

C++的协程(协程函数)内部可以用co_await , co_yield.两个关键字挂起协程,co_return,关键字进行返回。

co_await

co_await调用一个awaiter对象(可以认为是一个接口),根据其内部定义决定其操作是挂起,还是继续,以及挂起,恢复时的行为。其呈现形式为

cw_ret = co_await  awaiter;

cw_ret 记录调用的返回值,其是awaiter的await_resume 接口返回值。

co_await 相对比较复杂,后面开一章详细讲。

co_yield

挂起协程。其出现形式是

co_yield  cy_ret;

cy_ret会保存在promise承诺对象中(通过yield_value函数)。在协程外部可以通过promise得到。

co_return

协程返回。其出现形式是

co_return cr_ret;

cr_ret会保存在promise承诺对象中(通过return_value函数)。在协程外部可以通过promise得到。要注意,cr_ret并不是协程的返回值。这个是有区别的。

C++协程的重要概念

C++ 的编译器如何识别协程函数呢?是通过函数返回值。C++ 协程函数的返回类型有要求,返回类型是result ,而result里面必须有一个子类型承诺对象(promise)

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
很抱歉,我无法提供代码示例,因为作为AI语言模型,我无法编写代码。但我可以为您解释一下协程的概念和用法。 协程Coroutine)是一种用户级的轻量级线程,也称为协作式多任务。它不同于操作系统内核级的线程,协程不会被操作系统内核调度,而是由用户代码控制。在协程中,一个线程可以有多个执行流,这些执行流在适当的时候可以相互切换,从而实现多任务并发。 协程是一种非常有用的编程技术,用于编写高效、可读性强、可维护的代码。协程通常用于异步编程,因为它可以在不阻塞主线程的情况下执行耗时的操作。 以下是一个可能的协程示例: ```python import asyncio async def coroutine_1(): print('Coroutine 1 started') await asyncio.sleep(1) print('Coroutine 1 finished') async def coroutine_2(): print('Coroutine 2 started') await asyncio.sleep(2) print('Coroutine 2 finished') async def main(): task1 = asyncio.create_task(coroutine_1()) task2 = asyncio.create_task(coroutine_2()) print('Main started') await asyncio.gather(task1, task2) print('Main finished') asyncio.run(main()) ``` 在上面的示例中,我们定义了两个协程函数 coroutine_1 和 coroutine_2,这些函数用于执行一些异步任务。然后我们定义了一个主函数 main,它创建了两个任务 task1 和 task2,这些任务会在协程函数中执行。最后,我们使用 asyncio.run() 函数来运行主函数,从而启动协程并等待它们完成。 在上面的示例中,我们使用了 asyncio 库来实现协程。asyncio 是 Python 3 中的一个标准库,它提供了一些工具和函数来编写协程代码。asyncio 库的主要组件是事件循环(Event Loop),它负责调度协程的执行。我们使用 asyncio.run() 函数来创建一个新的事件循环并运行协程。然后我们使用 asyncio.create_task() 函数来创建任务,这些任务会在协程函数中执行。最后,我们使用 asyncio.gather() 函数来等待所有任务完成。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值