文章目录
  1. 前言
  2. SO_RCVTIMEO与SO_SNDTIMEO选项
  3. SIGALRM信号
  4. I/O复用系统调用的超时参数

前言

服务器程序通常管理着众多的定时事件,服务器程序需要有效地组织这些事件,使之能在预期的时间点被触发且不影响服务器的主要逻辑。

为此,服务器程序将每个定时事件封装成定时器,并使用某种容器类数据结构(如链表、排序链表、时间轮)将所有的定时器串联起来以实现对定时事件的统一管理。

Linux提供了三种定时方法:(1)socket选项SO_RCVTIMEO与SO_SNDTIMEO;(2)SIGALRM信号;(3)I/O复用系统调用的超时参数。

SO_RCVTIMEO与SO_SNDTIMEO选项

其中,SO_RCVTIMEO选项仅对recv、recvmsg、accept这些数据接收系统调用有效;SO_SNDTIMEO选项仅对send、sendmsg、connect这些数据发送系统调用有效。

所有这些数据发送/接收系统调用(除connect)超时后的行为是:返回-1并设置errno为EAGAIN或EWOULDBLOCK;connect超时后的行为是:返回-1并设置errno为EINPROGRESS。

SIGALRM信号

由alarm/setitimer函数设置的实时闹钟一旦超时,将触发SIGALRM信号。从而可以利用SIGALRM信号的信号处理函数来处理定时任务。若要处理多个定时任务,则要在程序中不断触发SIGALRM信号,然后在SIGALRM的信号处理函数中执行到期的任务。

通常,SIGALRM信号按照固定周期T触发,因此,如果在每次SIGALRM信号触发后去处理到期的事件,那么该事件的实际处理时间与理想处理时间(即事件到期后立即处理)会存在误差,而这个误差不会超过T。可见定时周期T也反映了定时处理的精度。

I/O复用系统调用的超时参数

三组I/O复用系统调用的超时参数也能用于处理定时事件。由于I/O事件的到来也会导致I/O复用系统调用返回,而此时超时时间可能并未到期,因此程序需要不断更新定时参数以反映剩余的时间。