网络编程中的超时机制
调用级超时
阻塞IO的超时
使用alert信号,可以打断所有的系统调用,包括socket io;
recv, send 还可以设置socket 选项(SO_RCVTIMEO, SO_SNDTIMEO )来实现超时;
connect 调用系统本身提供了75秒的超时。
非阻塞模拟: select 一个socket 来模拟阻塞操作。 为什么要这样做的呢? [多线程处理alert信号比较麻烦(信号是进程全局共享的),也可能出现惊群现象(所有线程都醒来了)]。
任务级超时
通用超时机制(主动注册法)
超时任务少的时候,使用按时间排序的容器就可以实现(比如一个vector 内有 free_list, used_list, used_list 是排了序的)
任务多,但时间跨度不大时, 使用时间片数组方式,比如 list<task> timer[60] 包含60秒内的超时任务, 每个元素储存1s内的任务。
任务多,时间跨度大时,使用多级时间片数组,Linux kernel的timer就是用这种方式组织。
基于SOCKET的任务超时(被动检测法)
一个请求的处理时间,数据等待时间,发送时间不能超过某个值(防止死连接,浪费socket和资源)
这个实现可以比较巧妙,不是通过设置超时来实现,而通过检测超时来实现。
每个socket的都注明它的活动时间,系统在每秒钟检测一次task队列,找出超时task,并执行超时task->on_timer操作。
这种方式的优点就在于,不需要主动设置超时,因为大多数连接都不会超时(这样节约了入队出队的时间,也没有了超时队列的空间开销)。