背景
协程分为有栈协程和无栈协程
有栈协程在每次挂起的时候,都需要保存一份堆栈,来存储当前的上下文
当协程频繁的挂起时,就会消耗大量的计算在保存堆栈上。
为了解决这个问题,提出了无栈协程。
无栈协程也在协程每次挂起时,保存堆栈,当对于一个函数,它就只有一份堆栈,它派生出来的子函数,都公用这一份堆栈。
这样就减少了保存堆栈的次数,实现性能的提升
编译器如何支持无栈协程
源程序
void* f(int n) {
void* hdl = CORO_BEGIN(malloc);
for (int i = n;; ++i) {
CORO_SUSPEND(hdl);
print(i);
CORO_SUSPEND(hdl);
print(-i);
}
CORO_END(hdl, free);
}
编译后的程序
struct f.frame {
int i;
};
void* f(int n) {
void* hdl = CORO_BEGIN(malloc); //malloc or fetch
f.frame* frame = (f.frame*)hdl;
switch (frame->suspend_index) {
case 1: goto r1;
case 2: goto r2;
}
for (frame->i = n;; ++frame->i) {
frame->suspend_index = 1;
r1: CORO_SUSPEND(hdl);
print(frame->i);
frame->suspend_index = 2;
r2: CORO_SUSPEND(hdl);
print(-frame->i);
}
CORO_END(hdl, free);
}
通过把协程函数,转换成状态机,把函数的栈变量,通过申请一片堆内存来维护,当需要把协程挂起时,则保存当前函数的frame保存起来,需要resume时,则通过frame,再次调用函数
网友评论