协程问题之为什么 C++20 的协程代码比其他语言的协程 demo 长很多如何解决

简介: 协程问题之为什么 C++20 的协程代码比其他语言的协程 demo 长很多如何解决

问题一:为什么 C++20 的协程代码比其他语言的协程 demo 长很多?

为什么 C++20 的协程代码比其他语言的协程 demo 长很多?


参考回答:

C++20 的协程代码比其他语言的协程 demo 长很多,是因为 C++ 想让程序员可以定制协程创建和执行的任意一个阶段的任意步骤的行为。为了实现这一目的,必须定义足够多的回调函数来定义每个阶段的行为,这增加了代码的复杂性。


关于本问题的更多回答可点击原文查看:https://developer.aliyun.com/ask/632254



问题二:在提供的 demo 中,TaskPromise 结构体起到了什么作用?

#include

#include

template

struct Awaiter {

bool await_ready() noexcept {

std::cout << "await_ready: " << READY << std::endl;

return READY;

}

void await_resume() noexcept {

std::cout << "await_resume" << std::endl;

}

void await_suspend(std::coroutine_handle<>) noexcept {

std::cout << "await_suspend" << std::endl;

}

};

struct TaskPromise {

struct promise_type {

TaskPromise get_return_object() {

std::cout << "get_return_object" << std::endl;

return TaskPromise{std::coroutine_handle::from_promise(*this)};

}

Awaiter initial_suspend() noexcept {

std::cout << "initial_suspend" << std::endl;

return {};

}

Awaiter final_suspend() noexcept {

std::cout << "final_suspend" << std::endl;

return {};

}

void unhandled_exception() {

std::cout << "unhandled_exception" << std::endl;

}

void return_void() noexcept {

std::cout << "return_void" << std::endl;

}

};

void resume() {

std::cout << "resume" << std::endl;

handle.resume();

}

std::coroutine_handle handle;

};

TaskPromise task_func() {

std::cout << "task first run" << std::endl;

co_await Awaiter{};

std::cout << "task resume" << std::endl;

}

int main() {

auto promise = task_func();

promise.resume();

return 0;

}

在提供的 demo 中,TaskPromise 结构体起到了什么作用?

#include

#include

template

struct Awaiter {

bool await_ready() noexcept {

std::cout << "await_ready: " << READY << std::endl;

return READY;

}

void await_resume() noexcept {

std::cout << "await_resume" << std::endl;

}

void await_suspend(std::coroutine_handle<>) noexcept {

std::cout << "await_suspend" << std::endl;

}

};

struct TaskPromise {

struct promise_type {

TaskPromise get_return_object() {

std::cout << "get_return_object" << std::endl;

return TaskPromise{std::coroutine_handle::from_promise(*this)};

}

Awaiter initial_suspend() noexcept {

std::cout << "initial_suspend" << std::endl;

return {};

}

Awaiter final_suspend() noexcept {

std::cout << "final_suspend" << std::endl;

return {};

}

void unhandled_exception() {

std::cout << "unhandled_exception" << std::endl;

}

void return_void() noexcept {

std::cout << "return_void" << std::endl;

}

};

void resume() {

std::cout << "resume" << std::endl;

handle.resume();

}

std::coroutine_handle handle;

};

TaskPromise task_func() {

std::cout << "task first run" << std::endl;

co_await Awaiter{};

std::cout << "task resume" << std::endl;

}

int main() {

auto promise = task_func();

promise.resume();

return 0;

}


参考回答:

TaskPromise 结构体用于定义协程的承诺(Promise)类型。它包含了一个 std::coroutine_handle 类型的成员变量 handle,用于管理协程的执行。同时,TaskPromise 的嵌套结构体 promise_type 定义了协程创建和执行过程中所需的各种回调函数,如 get_return_object、initial_suspend、final_suspend 等。


关于本问题的更多回答可点击原文查看:https://developer.aliyun.com/ask/632255



问题三:co_await Awaiter{}; 这行代码在协程中起到了什么作用?

#include

#include

template

struct Awaiter {

bool await_ready() noexcept {

std::cout << "await_ready: " << READY << std::endl;

return READY;

}

void await_resume() noexcept {

std::cout << "await_resume" << std::endl;

}

void await_suspend(std::coroutine_handle<>) noexcept {

std::cout << "await_suspend" << std::endl;

}

};

struct TaskPromise {

struct promise_type {

TaskPromise get_return_object() {

std::cout << "get_return_object" << std::endl;

return TaskPromise{std::coroutine_handle::from_promise(*this)};

}

Awaiter initial_suspend() noexcept {

std::cout << "initial_suspend" << std::endl;

return {};

}

Awaiter final_suspend() noexcept {

std::cout << "final_suspend" << std::endl;

return {};

}

void unhandled_exception() {

std::cout << "unhandled_exception" << std::endl;

}

void return_void() noexcept {

std::cout << "return_void" << std::endl;

}

};

void resume() {

std::cout << "resume" << std::endl;

handle.resume();

}

std::coroutine_handle handle;

};

TaskPromise task_func() {

std::cout << "task first run" << std::endl;

co_await Awaiter{};

std::cout << "task resume" << std::endl;

}

int main() {

auto promise = task_func();

promise.resume();

return 0;

}

co_await Awaiter{}; 这行代码在协程中起到了什么作用?

#include

#include

template

struct Awaiter {

bool await_ready() noexcept {

std::cout << "await_ready: " << READY << std::endl;

return READY;

}

void await_resume() noexcept {

std::cout << "await_resume" << std::endl;

}

void await_suspend(std::coroutine_handle<>) noexcept {

std::cout << "await_suspend" << std::endl;

}

};

struct TaskPromise {

struct promise_type {

TaskPromise get_return_object() {

std::cout << "get_return_object" << std::endl;

return TaskPromise{std::coroutine_handle::from_promise(*this)};

}

Awaiter initial_suspend() noexcept {

std::cout << "initial_suspend" << std::endl;

return {};

}

Awaiter final_suspend() noexcept {

std::cout << "final_suspend" << std::endl;

return {};

}

void unhandled_exception() {

std::cout << "unhandled_exception" << std::endl;

}

void return_void() noexcept {

std::cout << "return_void" << std::endl;

}

};

void resume() {

std::cout << "resume" << std::endl;

handle.resume();

}

std::coroutine_handle handle;

};

TaskPromise task_func() {

std::cout << "task first run" << std::endl;

co_await Awaiter{};

std::cout << "task resume" << std::endl;

}

int main() {

auto promise = task_func();

promise.resume();

return 0;

}


参考回答:

这行代码在协程中起到了挂起(Suspend)协程执行的作用。它调用 Awaiter 类型的对象的 await_suspend 方法,该方法负责将协程的执行状态保存到堆上,并将控制权交还给调用者。当协程需要恢复执行时,可以通过调用协程句柄的 resume 方法来实现。


关于本问题的更多回答可点击原文查看:https://developer.aliyun.com/ask/632257



问题四:在下面这个 demo 中,unhandled_exception 方法的作用是什么?

#include

#include

template

struct Awaiter {

bool await_ready() noexcept {

std::cout << "await_ready: " << READY << std::endl;

return READY;

}

void await_resume() noexcept {

std::cout << "await_resume" << std::endl;

}

void await_suspend(std::coroutine_handle<>) noexcept {

std::cout << "await_suspend" << std::endl;

}

};

struct TaskPromise {

struct promise_type {

TaskPromise get_return_object() {

std::cout << "get_return_object" << std::endl;

return TaskPromise{std::coroutine_handle::from_promise(*this)};

}

Awaiter initial_suspend() noexcept {

std::cout << "initial_suspend" << std::endl;

return {};

}

Awaiter final_suspend() noexcept {

std::cout << "final_suspend" << std::endl;

return {};

}

void unhandled_exception() {

std::cout << "unhandled_exception" << std::endl;

}

void return_void() noexcept {

std::cout << "return_void" << std::endl;

}

};

void resume() {

std::cout << "resume" << std::endl;

handle.resume();

}

std::coroutine_handle handle;

};

TaskPromise task_func() {

std::cout << "task first run" << std::endl;

co_await Awaiter{};

std::cout << "task resume" << std::endl;

}

int main() {

auto promise = task_func();

promise.resume();

return 0;

}

在下面这个 demo 中,unhandled_exception 方法的作用是什么?

#include

#include

template

struct Awaiter {

bool await_ready() noexcept {

std::cout << "await_ready: " << READY << std::endl;

return READY;

}

void await_resume() noexcept {

std::cout << "await_resume" << std::endl;

}

void await_suspend(std::coroutine_handle<>) noexcept {

std::cout << "await_suspend" << std::endl;

}

};

struct TaskPromise {

struct promise_type {

TaskPromise get_return_object() {

std::cout << "get_return_object" << std::endl;

return TaskPromise{std::coroutine_handle::from_promise(*this)};

}

Awaiter initial_suspend() noexcept {

std::cout << "initial_suspend" << std::endl;

return {};

}

Awaiter final_suspend() noexcept {

std::cout << "final_suspend" << std::endl;

return {};

}

void unhandled_exception() {

std::cout << "unhandled_exception" << std::endl;

}

void return_void() noexcept {

std::cout << "return_void" << std::endl;

}

};

void resume() {

std::cout << "resume" << std::endl;

handle.resume();

}

std::coroutine_handle handle;

};

TaskPromise task_func() {

std::cout << "task first run" << std::endl;

co_await Awaiter{};

std::cout << "task resume" << std::endl;

}

int main() {

auto promise = task_func();

promise.resume();

return 0;

}


参考回答:

unhandled_exception 方法是协程承诺(Promise)类型中的一个回调函数,用于处理协程执行过程中未捕获的异常。当协程中抛出了未被捕获的异常时,编译器会自动调用该方法。在这个 demo 中,unhandled_exception 方法只是简单地打印了一条错误信息。


关于本问题的更多回答可点击原文查看:https://developer.aliyun.com/ask/632260



问题五:如何理解编译器将协程代码展开成更复杂的代码的过程?

如何理解编译器将协程代码展开成更复杂的代码的过程?


参考回答:

编译器将协程代码展开成更复杂的代码的过程可以看作是一种代码生成(Code Generation)技术。编译器通过分析协程代码中的 co_await、co_return 等特殊语法,以及程序员定义的协程承诺(Promise)类型中的回调函数,生成出能够正确管理协程执行状态的代码。这些生成的代码会处理协程的挂起、恢复、异常处理等操作,以确保协程能够按照预期的方式执行。


关于本问题的更多回答可点击原文查看:https://developer.aliyun.com/ask/632261

相关文章
|
3月前
|
安全 Go
Golang语言goroutine协程并发安全及锁机制
这篇文章是关于Go语言中多协程操作同一数据问题、互斥锁Mutex和读写互斥锁RWMutex的详细介绍及使用案例,涵盖了如何使用这些同步原语来解决并发访问共享资源时的数据安全问题。
100 4
|
1月前
|
算法 安全 C++
提高C/C++代码的可读性
提高C/C++代码的可读性
53 4
|
2月前
|
安全 Go 调度
探索Go语言的并发模式:协程与通道的协同作用
Go语言以其并发能力闻名于世,而协程(goroutine)和通道(channel)是实现并发的两大利器。本文将深入了解Go语言中协程的轻量级特性,探讨如何利用通道进行协程间的安全通信,并通过实际案例演示如何将这两者结合起来,构建高效且可靠的并发系统。
|
2月前
|
算法 C++
2022年第十三届蓝桥杯大赛C/C++语言B组省赛题解
2022年第十三届蓝桥杯大赛C/C++语言B组省赛题解
51 5
|
2月前
|
Linux C语言 C++
vsCode远程执行c和c++代码并操控linux服务器完整教程
这篇文章提供了一个完整的教程,介绍如何在Visual Studio Code中配置和使用插件来远程执行C和C++代码,并操控Linux服务器,包括安装VSCode、安装插件、配置插件、配置编译工具、升级glibc和编写代码进行调试的步骤。
356 0
vsCode远程执行c和c++代码并操控linux服务器完整教程
|
3月前
|
Go 调度
Golang语言goroutine协程篇
这篇文章是关于Go语言goroutine协程的详细教程,涵盖了并发编程的常见术语、goroutine的创建和调度、使用sync.WaitGroup控制协程退出以及如何通过GOMAXPROCS设置程序并发时占用的CPU逻辑核心数。
72 4
Golang语言goroutine协程篇
|
2月前
|
存储 编译器 C语言
深入计算机语言之C++:类与对象(上)
深入计算机语言之C++:类与对象(上)
|
2月前
|
存储 分布式计算 编译器
深入计算机语言之C++:C到C++的过度-2
深入计算机语言之C++:C到C++的过度-2
|
2月前
|
编译器 Linux C语言
深入计算机语言之C++:C到C++的过度-1
深入计算机语言之C++:C到C++的过度-1
|
3月前
|
C++
继续更新完善:C++ 结构体代码转MASM32代码
继续更新完善:C++ 结构体代码转MASM32代码