在Linux系统中,协程是一种轻量级的线程,它们允许在多个任务之间切换,而不需要操作系统的线程调度。协程可以分为有栈协程和无栈协程,以及对称协程和非对称协程。
有栈协程
有栈协程每个协程都有自己的栈空间,允许协程在执行过程中保存局部变量和函数调用栈。切换协程时,保存和恢复整个栈的内容。
示例:
#include <ucontext.h>
#include <iostream>ucontext_t ctx_main, ctx_func;void func() {std::cout << "Inside coroutine\n";swapcontext(&ctx_func, &ctx_main);std::cout << "Back in coroutine\n";
}int main() {char stack[8192];getcontext(&ctx_func);ctx_func.uc_stack.ss_sp = stack;ctx_func.uc_stack.ss_size = sizeof(stack);ctx_func.uc_link = &ctx_main;makecontext(&ctx_func, func, 0);std::cout << "Starting coroutine\n";swapcontext(&ctx_main, &ctx_func);std::cout << "Back in main\n";swapcontext(&ctx_main, &ctx_func);std::cout << "Finished\n";return 0;
}
无栈协程
无栈协程不需要独立的栈空间,通常通过状态机实现。每次切换时,只保存和恢复必要的状态信息。
示例:
#include <iostream>class Coroutine {
public:Coroutine() : state(0) {}bool resume() {switch (state) {case 0:std::cout << "Inside coroutine\n";state = 1;return true;case 1:std::cout << "Back in coroutine\n";state = 2;return true;case 2:return false;}return false;}private:int state;
};int main() {Coroutine coro;std::cout << "Starting coroutine\n";while (coro.resume());std::cout << "Finished\n";return 0;
}
对称协程
对称协程允许协程之间相互调用和切换,没有主协程的概念。
非对称协程
非对称协程有一个主协程,其他协程只能返回到主协程,不能直接相互调用。
C++20的协程
C++20引入的协程是无栈协程,并且是非对称协程。它们通过编译器生成状态机来管理协程的状态。
示例:
#include <coroutine>
#include <iostream>struct ReturnObject {struct promise_type {ReturnObject get_return_object() { return {}; }std::suspend_never initial_suspend() { return {}; }std::suspend_never final_suspend() noexcept { return {}; }void return_void() {}void unhandled_exception() {}};
};ReturnObject foo() {std::cout << "Inside coroutine\n";co_await std::suspend_always{};std::cout << "Back in coroutine\n";
}int main() {auto coro = foo();std::cout << "Starting coroutine\n";coro.resume();std::cout << "Finished\n";return 0;
}