• 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;
    }
  • 相关阅读:
    红楼【建筑位置】
    红楼【人物关系】
    jenkins【shared-libraries】
    linux 安装mysql8.0 tar.xz
    MySQL 输入字符串对日期进行模糊查询
    解决kali linux 和 win10 双系统时间不一致问题
    linux idea桌面图标
    linux卸载openjdk11
    tar.xz解压
    pandas模块高性能使用方法总结
  • 原文地址:https://www.cnblogs.com/sniperHW/p/2556443.html
Copyright © 2020-2023  润新知