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* ); #endifcoro.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 ; }?
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
