• C协程使用举例


    C协程使用举例 - sniperHW - 博客园

    C协程使用举例

    本篇使用上一篇提供的接口,实现一个简单的协程调度框架.

    基本思想是,创建一个调度器,用于将处于活动状态的协程调度运行,调度器维护着一个actived列表,

    调用spawn创建协程时,将新建立的协程添加到活动列表中。

    调用schedule将启动调度器主循环.

    coro.h

    复制代码
    #ifndef _CORO_H
    #define _CORO_H
    #include <stdint.h>
    #include "uthread.h"
    
    struct coro
    {
        struct coro *next;
        uthread_t ut;
        uint32_t id;
        start_fun st_fun;
        uint32_t is_end;
    };
    
    struct testarg
    {
        struct coro *sche;
        struct coro *co;
    };
    
    void* yield(struct coro*,struct coro*,void *);
    void* resume(struct coro*,struct coro*,void *);
    
    struct scheduler
    {
        struct coro *active;  //处于激活态的coro
        struct coro *self;
    };
    
    struct scheduler *scheduler_create();
    //生成一个coro运行start_run
    void spawn(struct scheduler*,void *stack,uint32_t stack_size,start_fun);
    //调度coro运行
    void schedule(struct scheduler*);
    
    #endif
    复制代码

    coro.c

    复制代码
    #include "coro.h"
    #include <stdlib.h>
    #include <time.h>
    
    void* yield(struct coro *from,struct coro *to,void *arg)
    {
        return uthread_swtch(from->ut,to->ut,arg);
    }
    
    void* resume(struct coro *from,struct coro *to,void *arg)
    {
        return uthread_swtch(from->ut,to->ut,arg);
    }
    
    static uint32_t g_index = 0;
    
    static void* coro_start_fun(void *arg)
    {
        struct testarg *_arg = (struct testarg *)arg;
        void *ret = _arg->co->st_fun(_arg);
        _arg->co->is_end = 1;
        return ret;
    }
    
    void spawn(struct scheduler *sche,void *stack,uint32_t stack_size,start_fun st_fun)
    {
        uthread_t ut = uthread_create(stack,stack_size);
        struct coro *co = (struct coro*)malloc(sizeof(*co));
        co->ut = ut;
        co->st_fun = st_fun;
        co->id = ++g_index;
        //添加到激活队列中
        co->next = sche->active;
        co->is_end = 0;
        sche->active = co;
        uthread_make(co->ut,sche->self->ut,coro_start_fun);
    }
    
    struct scheduler *scheduler_create()
    {
        struct scheduler *sche = (struct scheduler *)malloc(sizeof(*sche));
        sche->active = 0;
        sche->self = (struct coro*)malloc(sizeof(*sche->self));
        sche->self->ut = uthread_create(0,0);
        return sche;
    }
    
    void schedule(struct scheduler *sche)
    {
        while(1)
        {
            if(sche->active)
            {
                struct coro *cur = sche->active;
                sche->active = 0;
                while(cur)
                {
                    struct testarg arg = {sche->self,cur};
                    resume(sche->self,cur,&arg);
                    struct coro *tmp = cur->next;
                    if(!cur->is_end)
                    {
                        cur->next = sche->active;
                        sche->active = cur;
                        cur = tmp;
                    }
                    else
                    {
                        uthread_destroy(&(cur->ut));
                        free(cur);
                    }
                    cur = tmp;
                }
            }
            else
                break;
        }
    
    }
    复制代码

    test.c

    复制代码
    #include <stdio.h>
    #include <stdlib.h>
    #include <stdint.h>
    #include "uthread.h"
    #include "coro.h"
    
    void* fun(void *arg)
    {
        struct testarg *_arg = (struct testarg *)arg;
        int i = 0;
        while(i<10)
        {
           printf("%d\n",_arg->co->id);
           yield(_arg->co,_arg->sche,0);
           ++i;
        }
        return 0;
    }
    
    int main()
    {
        struct scheduler *sche = scheduler_create();
        spawn(sche,malloc(4096),4096,fun);
        spawn(sche,malloc(4096),4096,fun);
        spawn(sche,malloc(4096),4096,fun);
        spawn(sche,malloc(4096),4096,fun);
        schedule(sche);
        return 0;
    }
    复制代码
  • 相关阅读:
    Vmware安装Ubuntu ==> 连网成功
    在 ns3.25中添加 plc(电力线载波) 模块
    Ubuntu12.04下安ns3.29及Ubuntu换源方法
    微信支付小程序版
    微信小程序打开外部链接
    linux下安装Mongodb
    延迟执行+异步 之代码分析1
    Vue入门
    实验一
    实验二
  • 原文地址:https://www.cnblogs.com/lexus/p/2581113.html
Copyright © 2020-2023  润新知