超时问题,同步比较简单,异步要在yield中处理,它的最后一个参数就是timeout。epoll对于单个fd的超时也没有什么好办法。
我的做法是每一步都在context中打时间戳。
记得主线程吗?它除了负责接生,另一个任务就是定期检查各个队列中超时的context。超时后会进行夭折处理。在IO中,yield也是进行TIMEOUT状态的返回,然后整个函数返回TIMEOUT状态。协程自行了断。
while(1) {
do {
FD_ZERO(&efds);
FD_SET(sock, &efds);
//健康检查周期
tm.tv_sec=15;
tm.tv_usec=0;
ret=select(sock+1,&efds,NULL,&efds,&tm);
if(ret==-1) {
ShowLog(1,"select error %s",strerror(errno));
close(sock);
quit(3);
}
if(ret==0) {
check_TCB_timeout();
if(poolchk) poolchk();
}
} while(ret<=0);
后边才是对select出来的进行accept。
超时之后,除了对交易进行夭折处理,还一个重要任务是对连接池的健康管理。对连接故障的判断,进行容错处理。
【 在 wallyz 的大作中提到: 】
: “如果异步操作出现任何异常,就立即转换为同步模式,不会耽误事。”
: 我对这里也感觉纳闷
: 异步出现非正常情况,除了连接断掉之外,无外乎是EAGAIN/EWOULDBLOCK,也就是read没数据或者write缓冲区满,这时候转成同步模式是不合适的,转成同步模式会阻塞当前线程,这样做和就地poll这个socket没啥两样,都会造成线程被阻塞
: ...................
--
修改:ylh0315 FROM 221.218.61.*
FROM 221.218.61.*