C++中的协程是什么?C++20协程基础与应用详解

来源:站长素材作者:杨建军头衔:草根站长
导读:本期聚焦于小伙伴创作的《C++中的协程是什么?C++20协程基础与应用详解》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《C++中的协程是什么?C++20协程基础与应用详解》有用,将其分享出去将是对创作者最好的鼓励。

C++中的协程是一种可以暂停执行并在后续恢复的特殊函数,它不属于传统的线程调度模型,而是由程序自身控制执行流程,相比线程更加轻量,适合处理异步、延迟执行等场景。C++20标准正式将协程纳入语言特性,提供了一套原生的协程语法支持。

C++协程的核心概念

传统函数在调用时会从开始执行到结束返回,中间无法暂停。而协程可以在执行过程中主动暂停,保存当前的执行状态,之后在合适的时机从暂停的位置继续执行。这种特性让协程非常适合处理需要等待外部资源的场景,比如网络请求、文件读写等,不需要阻塞当前线程,提升程序的并发处理能力。

和普通函数相比,C++协程有以下几个典型特征:

  • 函数体内可以使用co_awaitco_yieldco_return三个关键字,只要使用了其中一个,函数就会被编译器识别为协程
  • 协程的返回类型不是普通的类型,需要满足协程返回类型的约定,包含特定的成员函数或者类型定义
  • 协程暂停时会保存当前的局部变量、指令指针等状态,恢复时可以完整还原执行上下文

C++20协程的关键语法

三个核心关键字

C++20为协程提供了三个专用关键字,分别承担不同的作用:

  • co_await:用于暂停当前协程的执行,等待一个可等待对象(awaitable)的结果,等待完成后再恢复协程继续执行
  • co_yield:用于暂停协程并返回一个值给调用方,调用方可以后续再次恢复协程执行,常用于生成器场景
  • co_return:用于协程执行结束返回最终结果,作用和普通函数的return类似,但只能用于协程中

协程返回类型的要求

协程的返回类型不能是int、void这类普通类型,需要满足一定的约定。简单来说,返回类型需要包含以下部分:

  • 一个promise_type内部类型,用于协程状态的创建和管理
  • promise_type需要定义get_return_objectinitial_suspendfinal_suspendreturn_voidreturn_value等成员函数,控制协程的初始化、暂停、结束等行为

下面是一个简单的返回类型定义示例:

#include <coroutine>
#include <iostream>

// 简单的协程返回类型
struct SimpleCoroutine {
    struct promise_type {
        SimpleCoroutine get_return_object() {
            return SimpleCoroutine{std::coroutine_handle<promise_type>::from_promise(*this)};
        }
        std::suspend_never initial_suspend() { return {}; }
        std::suspend_never final_suspend() noexcept { return {}; }
        void return_void() {}
        void unhandled_exception() { std::terminate(); }
    };

    std::coroutine_handle<promise_type> handle;
};

C++20协程基础应用示例

简单协程示例

下面是一个最基础的协程示例,展示协程的暂停和恢复过程:

#include <coroutine>
#include <iostream>
#include <thread>
#include <chrono>

struct SimpleCoroutine {
    struct promise_type {
        SimpleCoroutine get_return_object() {
            return SimpleCoroutine{std::coroutine_handle<promise_type>::from_promise(*this)};
        }
        std::suspend_never initial_suspend() { return {}; }
        std::suspend_always final_suspend() noexcept { return {}; }
        void return_void() {}
        void unhandled_exception() { std::terminate(); }
    };

    std::coroutine_handle<promise_type> handle;
};

// 协程函数
SimpleCoroutine test_coroutine() {
    std::cout << "协程开始执行" << std::endl;
    co_await std::suspend_always{}; // 暂停协程
    std::cout << "协程恢复执行" << std::endl;
    co_return;
}

int main() {
    auto coro = test_coroutine();
    std::cout << "主函数继续执行" << std::endl;
    // 恢复协程执行
    if (coro.handle && !coro.handle.done()) {
        coro.handle.resume();
    }
    // 销毁协程句柄
    if (coro.handle) {
        coro.handle.destroy();
    }
    return 0;
}

上述代码的执行输出顺序为:协程开始执行、主函数继续执行、协程恢复执行。可以看到协程在co_await处暂停后,主函数可以继续执行其他逻辑,之后手动恢复协程才会继续执行后续内容。

生成器场景应用

co_yield关键字非常适合实现生成器,下面的示例实现了一个简单的整数序列生成器:

#include <coroutine>
#include <iostream>

// 生成器返回类型
template<typename T>
struct Generator {
    struct promise_type {
        T current_value;
        Generator get_return_object() {
            return Generator{std::coroutine_handle<promise_type>::from_promise(*this)};
        }
        std::suspend_always initial_suspend() { return {}; }
        std::suspend_always final_suspend() noexcept { return {}; }
        void return_void() {}
        void unhandled_exception() { std::terminate(); }
        std::suspend_always yield_value(T value) {
            current_value = value;
            return {};
        }
    };

    std::coroutine_handle<promise_type> handle;

    // 迭代器相关定义
    struct iterator {
        std::coroutine_handle<promise_type> handle;
        bool operator!=(const iterator& other) const {
            return handle && !handle.done();
        }
        iterator& operator++() {
            handle.resume();
            return *this;
        }
        T operator*() const {
            return handle.promise().current_value;
        }
    };

    iterator begin() {
        handle.resume();
        return iterator{handle};
    }
    iterator end() {
        return iterator{nullptr};
    }
};

// 生成0到n-1的序列协程
Generator<int> range(int n) {
    for (int i = 0; i < n; ++i) {
        co_yield i;
    }
}

int main() {
    for (int val : range(5)) {
        std::cout << val << " ";
    }
    // 输出:0 1 2 3 4
    return 0;
}

协程使用注意事项

在使用C++20协程时需要注意以下几点:

  • 协程的返回类型需要严格遵守约定,否则编译器会直接报错,实际开发中可以使用标准库或者第三方库封装好的返回类型,减少重复开发
  • 协程的暂停和恢复不会自动进行线程切换,默认还是在当前线程执行,如果需要跨线程调度,需要自定义可等待对象的await_suspend逻辑
  • 协程句柄需要手动管理生命周期,使用完成后要及时销毁,避免内存泄漏
  • 不是所有编译器都完全支持C++20协程特性,使用前需要确认编译器的支持情况,比如GCC 10+、Clang 14+、MSVC 2019+版本都提供了较好的支持

C++20coroutine协程co_await修改时间:2026-06-18 17:03:31

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。