在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;
}