ontheroad怎么读([OnTheRoad]Linux C 的http服务器.)
导读:[OnTheRoad]Linux C 的http服务器. C协程使用举例...
[OnTheRoad]Linux C 的http服务器.
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;
}
声明:本站所有文章 ,如无特殊说明或标注 ,均为本站原创发布 。任何个人或组织 ,在未征得本站同意时 ,禁止复制 、盗用 、采集 、发布本站内容到任何网站 、书籍等各类媒体平台 。如若本站内容侵犯了原著者的合法权益 ,可联系我们进行处理 。
创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!