deepwzh的技术笔记
  • Golang
  • Python
  • Cpp
杂项
前端开发
  • 计算机网络
  • 操作系统
  • 数据库
云原生
Devops
AIGC
关于作者
  • Golang
  • Python
  • Cpp
杂项
前端开发
  • 计算机网络
  • 操作系统
  • 数据库
云原生
Devops
AIGC
关于作者
  • Cpp
  • c++ 模块
  • 类

    • 类
    • 友元
  • 开发工具

    • 开发工具
    • Vscode

      • Vscode
      • vscode 相关插件
  • 协程

    • 协程
    • test
  • 构建工具

    • 构建工具
    • Make
    • Cmake

      • Cmake
      • 常见问题
      • cmake 基本用法
      • cmake 集成 conan
      • cmake 生成器
      • cmake 库查找
  • 链接库

    • 链接库
    • 动态链接库
  • 编译器

    • 编译器
    • gcc

      • gcc
      • 常用选项
  • 包管理工具

    • 包管理工具
    • Canan

协程

  • C++ 基于汇编实现的协程与 ucontext_t 版本有以下几个区别:

    • 基于汇编实现的协程可以直接操作函数的上下文,而 ucontext_t 版本需要通过库函数来获取和设置上下文(1)(2)。
    • 基于汇编实现的协程可以更精确地控制栈空间的分配和释放,而 ucontext_t 版本需要依赖系统提供的栈空间(1)(3)。
    • 基于汇编实现的协程可以更好地适应不同的平台和编译器,而 ucontext_t 版本可能存在兼容性问题,因为 ucontext 库已被标记为过时(2)(3)。

    根据网上的一些资料,ucontext.h 是 GNU C 库的一个头文件,主要用于用户态下的上下文切换。但是由于 makecontext 中设计的一些问题,该文件已经被标记为过时的(1)。一些可能的原因是:

    • ucontext 函数族不符合 POSIX 标准,不具有跨平台性(2)。
    • ucontext 函数族在内存管理和异常处理方面存在一些缺陷(3)。
    • ucontext 函数族的性能比不上其他实现协程的方式,如汇编代码或 switch-case 技巧(3)。 如果需要类似的功能,可以看一下 Boost 提供的 fcontext(1),它是一个更加现代和高效的协程库。
  • 有栈协程和无栈协程?

    • 有栈协程:通过保存运行时的堆栈及运行时的上下文来保存运行状态,需要改变调用栈。
    • 无栈协程:通过闭包或者状态机的方法记录程序的运行状态,不改变调用栈。
    • 对称协程:各协程之间可以进行执行权的切换。
    • 非对称协程:有一个中心化的调度器,所有协程都只和调度器进行执行权的切换。
  • 有栈协程的实现方式?

    • 使用 C 标准函数库的 setjmp 和 longjmp 函数
    • 使用 POSIX 标准中的 ucontext 库,但是这个库已被标记为 obsolete
    • 使用汇编直接对函数上下文进行操作
  • 有哪些三方的协程库?libco?

    • libco 是微信后台大规模使用的 c/c++ 协程库,它支持同步或者异步的写法,也提供了 socket 族函数的 hook,使得后台逻辑服务几乎不用修改逻辑代码就可以完成异步化改造(1)。
    • libco 使用共享栈模式来实现协程,即每个线程只有一个栈空间,所有该线程上的协程都共享这个栈空间。这样可以节省内存空间,也可以支持更多的协程(2)。
    • libco 使用汇编代码来实现上下文切换,即保存和恢复寄存器和栈指针。libco 支持 x86、x64、arm、arm64 等多种平台(3)。
    • libco 提供了几个函数接口来创建、恢复和暂停协程。其中 co_create 用于创建一个新的协程;co_resume 用于恢复一个已经暂停的协程;co_yield 用于暂停当前运行的协程;co_poll 用于等待事件发生并调度相应的协程(4)。
  • C++20 / C++23 的协程了解吗?

    • C++20 中的协程是非对称的、一等对象、无栈的。非对称意味着有一个中心化的调度器来控制协程之间的转移;一等对象意味着协程可以作为函数参数或返回值;无栈意味着每个协程不需要分配一个固定大小的栈空间。
    • C++20 中使用 co_await、co_yield 和 co_return 关键字来标记协程暂停点和恢复点。co_await 用于等待一个异步操作完成;co_yield 用于生成一个值并暂停;co_return 用于返回一个值并结束。
    • C++23 可能会提供更高层次的库来支持协程,比如 generator、task、future 等。这样就可以直接使用协程而不需要自己实现底层细节。
  1. 基于 ucontext_t 实现协程的具体原理?

子文档

  • test
Next
test