无栈协程原理

背景

协程分为有栈协程和无栈协程

有栈协程在每次挂起的时候,都需要保存一份堆栈,来存储当前的上下文

当协程频繁的挂起时,就会消耗大量的计算在保存堆栈上。

为了解决这个问题,提出了无栈协程。

无栈协程也在协程每次挂起时,保存堆栈,当对于一个函数,它就只有一份堆栈,它派生出来的子函数,都公用这一份堆栈。

这样就减少了保存堆栈的次数,实现性能的提升

编译器如何支持无栈协程

源程序

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,再次调用函数

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。
禁止转载,如需转载请通过简信或评论联系作者。

推荐阅读更多精彩内容