Libfly协程库实现与原理——协程的实现与基本操作的实现


Libfly协程库简介:
libfly协程库,采用C++作为编程语言,封装了协程类,并提供了协程基本操作和调度功能
编写此协程库的目的是为了让协程理解起来更容易,让协程编程更加简单!
正逐步完善代码注释与文档,欢迎大家一起讨论交流~

Github地址:https://github.com/chudongfang/libfly


一、协程的实现

与线程类似一个协程包括以下三个方面:
(1) 有一段程序供其执行,不同的协程可以共用同一段程序。
(2) 与线程一样,协程有专属的系统堆栈空间。
(3) 一个存储协程相关信息的协程控制块,这里我把其封装在一个协程类中。
协程类

先来看一下协程类,其描述了一个协程,包含了协程的所有信息。

//协程块
class Routine 
{
public:
    Routine(RoutineEnv * env,const RoutineAttr* attr ,void*(*pfn)(void*),void *arg );
    ~Routine();
    void resume();   //运行当前协程
    void yield();    //退出当前协程
public:

    RoutineEnv * env_;                //当前协程环境
    Routine_Function pfn_;            //协程块函数
    void* arg_;                       //协程块函数对应的参数
    coctx_t ctx_;                     //用来保存CPU上下文

    char Start_;                      //协程是否运行
    char End_;                        //协程是否结束
    char IsMainRoutine_;              //是否是主协程

    StackMemry* stack_memry_;         //协程运行栈内存

    char* stack_sp_;                  //顶指针
    unsigned int save_size_;          //buff大小
    char* save_buffer_;               //buff

    unsigned long long getId() const  //获取协程ID
    {  return Id_; }

    void setId(unsigned long long Id) //设置协程ID
    { Id_ = Id; }

private:
    unsigned long long Id_;           //协程ID
};


栈内存 stack_memry_

其中 stack_memry_ 为其栈内存,记录协程运行过程中的信息。


//协程栈
class StackMemry
{
public:
    StackMemry(int stack_size);
public:
    Routine* occupy_co_;     //当前协程指针
    int      stack_size_;    //栈大小
    char*    stack_bp_;      //stack_buffer + stack_size
    char*    stack_buffer_;  //栈空间

};





协程的创建

好,看完协程快的结构,下面来看一下如何创建一个协程

//构造函数原型
//env  当前线程enb
//attr 协程栈参数
//void*(*Func)(void*) 协程函数
//arg  协程函数参数
Routine(RoutineEnv * env,const RoutineAttr* attr ,void*(*Func)(void*),void *arg );

// for example

void* Func(void *arg)
{
    int* x = (int*)arg;
    std::cout<<*x<<std::endl;
}
int x = 1;
Routine  * routine = new Routine(get_curr_thread_env(),NULL,Func,&x);

其中的Func就是协程函数,其为将要在协程中执行的函数。由用户提供。


二、基本操作的实现

协程 resume 唤醒/执行

前面已经创建了一个协程,那么如何唤醒它那?

//routine->resume();

void* Func(void *arg)
{
    int* x = (int*)arg;
    std::cout<<*x<<std::endl;
}
int x = 1;
Routine  * routine = new Routine(get_curr_thread_env(),NULL,Func,&x);
routine->resume();

resume 内部实现:

//执行本协程
void Routine::resume()
{

    RoutineEnv *env = env_;
    Routine *Current_Routine = env->CallStack_[ env->CallStackSize_ - 1 ]; //取当前协程块指针 
    //std::cout<<env->CallStackSize_<<std::endl;
    //协程首次执行,创建其上下文
    if( !Start_ )
    {
        coctx_make( &ctx_,(coctx_pfn_t)RoutineFunc,this,0 );
        Start_ = 1;
    }

    env->CallStack_[ env->CallStackSize_++ ] = this;//将新协程块指针压入pCallStack栈中
    co_swap( Current_Routine, this );     
}

其就是把当前协程的寄存器信息和指针信息与入寄存器,co_swap coctx_make 都是用来复制寄存器信息的,这个放到后面解释。RoutineEnv是存储当前进程中协程信息的这个放到后面会有专门的解释。


协程 yield 退出
//routine->yiled();

void* Func(void *arg)
{
    int* x = (int*)arg;
    std::cout<<*x<<std::endl;
}
int x = 1;
Routine  * routine = new Routine(get_curr_thread_env(),NULL,Func,&x);
routine->resume();
routine->yiled();

yiled 实现原理


//退出本协程
void Routine::yield()
{
    //确保不重复退出协程
    assert(End_ == 0 && Start_ == 1);
    yield_env(env_);
}

void yield_env(RoutineEnv* env_)
{
    Routine *Last_routine    = env_->CallStack_[ env_->CallStackSize_ - 2 ]; //获取上一个协程块
    Routine *Current_Routine = env_->CallStack_[ env_->CallStackSize_ - 1 ]; //获取当前协程块

    env_->CallStackSize_--;
    co_swap( Current_Routine, Last_routine);
}
其实也很简单,获取上一个协程块后,退出当前协程,把上一个协程信息写入寄存器就OK了。

在协程类离开作用域或者被delete后,会自动调用析构函数,释放栈空间。

协程的基本简单实现就到这里了,接下来还会有 协程寄存器切换 ,定时器,事件驱动EventLoop ,
RoutineEnv等内容~

Python网络爬虫与推荐算法新闻推荐平台:网络爬虫:通过Python实现新浪新闻的爬取,可爬取新闻页面上的标题、文本、图片、视频链接(保留排版) 推荐算法:权重衰减+标签推荐+区域推荐+热点推荐.zip项目工程资源经过严格测试可直接运行成功且功能正常的情况才上传,可轻松复刻,拿到资料包后可轻松复现出一样的项目,本人系统开发经验充足(全领域),有任何使用问题欢迎随时与我联系,我会及时为您解惑,提供帮助。 【资源内容】:包含完整源码+工程文件+说明(如有)等。答辩评审平均分达到96分,放心下载使用!可轻松复现,设计报告也可借鉴此项目,该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的。 【提供帮助】:有任何使用问题欢迎随时与我联系,我会及时解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 下载后请首先打开README文件(如有),项目工程可直接复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用。
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值