简易协程

it2025-09-16  4

简易协程

#include <stdio.h> #include <stdlib.h> #include <sys/time.h> #define assert(x) typedef unsigned int uint; typedef unsigned short ushort; typedef unsigned char uchar; typedef unsigned long ulong; // List struct LNode { void *pData; struct LNode *pNext; }; typedef LNode* PLNode; struct List { uint uCount; PLNode pHead; PLNode pTail; }; typedef List* PList; PList pListContainer; PLNode list_node_create() { PLNode pNode = (PLNode)malloc(sizeof(LNode)); pNode->pData = NULL; pNode->pNext = NULL; return pNode; } void list_node_free(PLNode pNode) { //assert(pNode != NULL); free((void*)pNode); } PList list_create() { PLNode pNode = list_node_create(); PList pList = (PList)malloc(sizeof(List)); pList->uCount = 0; pList->pHead = pNode; pList->pTail = pList->pHead; return pList; } void list_add(PList pList, void* pData) { assert(pList != NULL && pData != NULL); PLNode pNode = list_node_create(); pNode->pData = pData; pList->uCount++; pList->pTail->pNext = pNode; pList->pTail = pNode; } PLNode list_first_node(PList pList) { PLNode p; p = pList->pHead; return p->pNext; } PLNode list_last_node(PList pList) { return pList->pTail; } void list_remove(PList pList, PLNode pNode) { PLNode p, q; assert(pList != NULL && pNde != NULL); p = pList->pHead; q= p->pNext; while(q!= NULL) { if(q == pNode) { p->pNext = q->pNext; if(q->pNext == NULL) { pList->pTail = p; } pList->uCount--; break; } p = p->pNext; q = p->pNext; } } PLNode list_find(PList pList, uint pos) { PLNode p, q; uint i = 0; assert(pList != NULL); p = pList->pHead; q = p->pNext; while(q != NULL) { if(i == pos) { return q; } ++i; q = q->pNext; } return NULL; } #define INIT_STATE 0; #define crStart(pCRCB) switch( ( (CRCB*)(pCRCB) )->uState ) { case 0: #define crEnd() } #define crYield(pCRCB) \ AddCoRoutineToRedayQueue((pCRCB)); \ ( (CRCB*)(pCRCB) )->uState = (__LINE__*2); return; case (__LINE__*2): #define crYield2(pCRCB) \ ( (CRCB*)(pCRCB) )->uState = ((__LINE__*2)+1); return; case((__LINE__*2)+1): #define crDelay(pCRCB, ticksToDelay) \ if( (ticksToDelay) > 0) { \ pCRCB->uValue = GetTickCount() + (ticksToDelay); \ AddCoRoutineToDelayQueue((pCRCB)); \ } \ else { \ AddCoRoutineToRedayQueue((pCRCB)); \ } \ crYield2((pCRCB)); typedef void* CoRoutineHandle; typedef void (*CoRoutineFunc)(CoRoutineHandle, void*); typedef struct CoRoutineControlBlock { CoRoutineFunc pCoRoutineFunction; void* param; uint uValue; ushort uState; } CRCB; static void InitCoRoutineLists(); static uint GetTickCount(); static void UpdateTicksCount(); static void AddCoRoutineToRedayQueue(CRCB*); static void AddCoRoutineToDelayQueue(CRCB*); CRCB *pCurrentCoRoutine = NULL; static PList pCoRoutineDelayList = NULL; static PList pCoRoutineReadyList = NULL; static uint uLastTickCount= 0; static uint uCurReadyIndexList = 0; static uint uTicksCount = 0; // 创建协程 ushort CoRoutineCreate(CoRoutineFunc pCoRountineFunc, void* param) { CRCB *pCoRoutine; InitCoRoutineLists(); pCoRoutine= (CRCB*)malloc(sizeof(CRCB)); if(pCoRoutine) { pCoRoutine->uState = INIT_STATE; pCoRoutine->pCoRoutineFunction = pCoRountineFunc; pCoRoutine->param = param; pCoRoutine->uValue = 0; AddCoRoutineToRedayQueue(pCoRoutine); return 0; } return -1; } static void InitCoRoutineLists() { if(pCoRoutineReadyList == NULL) { pCoRoutineReadyList = list_create(); } if(pCoRoutineDelayList == NULL) { pCoRoutineDelayList = list_create(); } } static uint GetTickCount() { return uTicksCount; } static void UpdateTicksCount() { ++uTicksCount; } static void AddCoRoutineToRedayQueue(CRCB* pCoRoutine) { list_add(pCoRoutineReadyList , (void*)pCoRoutine); } static void AddCoRoutineToDelayQueue(CRCB* pCoRoutine) { list_add(pCoRoutineDelayList, (void*)pCoRoutine); } // 检测延迟列表是否超时 void CheckDelayedList() { CRCB *pCRCB; PLNode p, q; PList pList ; uint uTick; uTick= GetTickCount(); pList = pCoRoutineDelayList; p = pList->pHead; q = p->pNext; while(q != NULL) { pCRCB = (CRCB*)(q->pData); if(uTick >= pCRCB->uValue){ p->pNext= q->pNext; AddCoRoutineToRedayQueue(pCRCB); list_node_free(q); q = p->pNext; } else{ p = q; q = q->pNext; } } } // 循环调度 void CoRoutineSchedule() { CRCB *pCRCB; PLNode pNode; PList pList, pWaitList; UpdateTicksCount(); CheckDelayedList(); pList = pCoRoutineReadyList ; pNode = list_first_node(pList); if(pNode != NULL) { list_remove(pList, pNode); pCRCB = (CRCB*)(pNode->pData); if(pCRCB != NULL){ (pCRCB->pCoRoutineFunction)(pCRCB, pCRCB->param); } } } // 使用例子 void CallBackCoRoutine(CoRoutineHandle pHandler, void* param) { CRCB *pCRCB; pCRCB = (CRCB*)pHandler; crStart(pCRCB); for( ;; ) { // do some thing ... printf("CR_1 ----> 1\n"); crDelay(pCRCB, 3000); // do some thing ... printf("CR_1 ----> 2\n"); crYield(pCRCB); printf("CR_1 ----> 3\n"); crEnd(); } } // 使用例子 void CallBackCoRoutine2(CoRoutineHandle pHandler, void* param) { CRCB *pCRCB; pCRCB = (CRCB*)pHandler; crStart(pCRCB); for( ;; ) { // do some thing ... printf("CR_2 >>>> 4\n"); crDelay(pCRCB, 5000); // do some thing ... printf("CR_2 >>>> 5\n"); crYield(pCRCB); printf("CR_2 >>>> 6\n"); crEnd(); } } long get_time_ms() { struct timeval tv; gettimeofday(&tv, NULL); return tv.tv_sec * 1000 + tv.tv_usec / 1000; } int main() { CoRoutineCreate(CallBackCoRoutine, 0); CoRoutineCreate(CallBackCoRoutine2, 0); long now, last_time; now = get_time_ms(); last_time = now + 10 * 1000; while(now<last_time){ CoRoutineSchedule(); now = get_time_ms(); } return 0; } 输出结果: CR_1 ----> 1 CR_2 >>>> 4 CR_1 ----> 2 CR_1 ----> 3 CR_1 ----> 1 CR_2 >>>> 5 CR_2 >>>> 6 CR_2 >>>> 4 CR_1 ----> 2 CR_1 ----> 3 CR_1 ----> 1 CR_1 ----> 2 CR_1 ----> 3 CR_1 ----> 1 CR_2 >>>> 5 CR_2 >>>> 6 CR_2 >>>> 4
最新回复(0)