C/C++协程学习笔记丨C/C++实现协程及原理分析视频( 七 )
apTimeout->llStartIdx = 0; // 当前时间轮指针指向数组0
}
// 1. 当前时间不可能小于时间轮的基准时间
// 2. 加入的定时器的超时时间不能小于当前时间
if( allNow < apTimeout->ullStart || apItem->ullExpireTime < allNow )
{
return __LINE__;
}
int diff = apItem->ullExpireTime - apTimeout->ullStart;
if( diff >= apTimeout->iItemSize ) // 添加的事件不能超过时间轮的大小
{
return __LINE__;
【C/C++协程学习笔记丨C/C++实现协程及原理分析视频】 }
// 插入到时间轮盘的指定位置
AddTail( apTimeout->pItems +
(apTimeout->llStartIdx + diff ) % apTimeout->iItemSize, apItem );
return 0;
}
定时器的超时检查在函数 co_eventloop 中执行 。
EPOLL 事件循环main 协程通过调用函数 co_eventloop 来监听 Epoll 事件 , 并在相应的事件触发时切换到指定的协程执行 。 有关 co_eventloop 与 应用协程的交互过程在上一节的流程图中已经比较清楚了 , 下面我们主要介绍一下 co_eventloop 函数的实现:
上文中也提到 , 通过 epoll_wait 返回的事件都保存在 stCoEpoll_t 结构的 co_epoll_res 中 。 因此 co_eventloop 首先为 co_epoll_res 申请空间 , 之后通过一个无限循环来监听所有 coroutine 添加的所有事件:
for(;;)
{
int ret = co_epoll_wait( ctx->iEpollFd,result,stCoEpoll_t::_EPOLL_SIZE, 1 );
...
}
对于每一个触发的事件 , co_eventloop 首先通过指针域 data.ptr 取出保存的 stPollItem_t 结构 , 并将其添加到 pstActiveList 列表中;之后从定时器轮盘中取出所有已经超时的事件 , 也将其全部添加到 pstActiveList 中 , pstActiveList 中的所有事件都作为活跃事件处理 。
对于每一个活跃事件 , co_eventloop 将通过调用对应的 pfnProcess 也就是上图中的OnPollProcessEvent 函数来切换到该事件对应的 coroutine , 将流程跳转到该 coroutine 处执行 。
最后 co_eventloop 在调用时也提供一个额外的参数来供调用者传入一个函数指针 pfn 。 该函数将会在每次循环完成之后执行;当该函数返回 -1 时 , 将会终止整个事件循环 。 用户可以利用该函数来控制 main 协程的终止或者完成一些统计需求 。
推荐阅读
- 计算机专业大一下学期,该选择学习Java还是Python
- 假期弯道超车 国美学习“神器”助孩子变身“学霸”
- 想自学Python来开发爬虫,需要按照哪几个阶段制定学习计划
- 未来想进入AI领域,该学习Python还是Java大数据开发
- Google AI建立了一个能够分析烘焙食谱的机器学习模型
- 学习大数据是否需要学习JavaEE
- 学习“时代楷模”精神 信息科技创新助跑5G智慧港口
- 非计算机专业的本科生,想利用寒假学习Python,该怎么入手
- 为什么我喜欢C语言,却非常讨厌C++?一位国外程序员的回答
- ?优学天下带着学习机冲刺上市,智能教育硬件有多烧钱?