ucontext 定义如下
The ucontext_t type is a structure type suitable for holding the context for a user thread of execution. A thread's context includes its stack, saved registers, and list of blocked signals.
可以用来保存当前线程的堆栈和寄存器,保存执行现场,这就为在一个线程内进行任务切换提供了可能,这种多任务之间的切换就是协程。
示例
#include <stdio.h>
#include <ucontext.h>
#include <unistd.h>
#include <iostream>
using namespace std;
void coroutine_1(void* arg)
{
puts("This is from coroutine 1");
}
void coroutine_2(void* arg)
{
puts("This is from coroutine 2");
}
定义两个任务 coroutine_1 和 coroutine_2
void context_test()
{
char stack_1[1024*128];
ucontext_t co_1, co_save_1;
getcontext(&co_1);
co_1.uc_stack.ss_sp = stack_1;
co_1.uc_stack.ss_size = sizeof(stack_1);
co_1.uc_stack.ss_flags = 0;
co_1.uc_link = &co_save_1;
makecontext(&co_1, (void(*)(void))coroutine_1, 0); // To coroutine_1
swapcontext(&co_save_1, &co_1);
puts("here 33 line");
char stack_2[1024*128];
ucontext_t co_2, co_save_2;
getcontext(&co_2);
co_2.uc_stack.ss_sp = stack_2;
co_2.uc_stack.ss_size = sizeof(stack_2);
co_2.uc_stack.ss_flags = 0;
co_2.uc_link = &co_save_2;
makecontext(&co_2, (void(*)(void))coroutine_2, 0); // To coroutine_2
swapcontext(&co_save_2, &co_2);
puts("here 45 line");
}
int main() {
context_test();
puts("here 50 line");
return 0;
}
用 co_1 表示一个新的 context,它指向下一个执行的 context 是 co_save_1。
makecontext 函数修改目前的上下文,去执行 coroutine_1 函数。swapcontext 触发任务切换,同时保存当前上下文到 co_save_1 中,一旦 coroutine_1 执行完会回到当前位置。
同理,用 co_2 表示另一个 context,它指向下一个执行的 context 是 co_save_2。
这样就可以看到如下执行顺序
context_test——> coroutine_1
coroutine_1 ——> context_test
context_test——> coroutine_2
coroutine_2 ——> context_test
context_test ——> main 结束
运行结果
This is from coroutine 1
here 33 line
This is from coroutine 2
here 45 line
here 50 line