定时器的基础知识

目录

socket选项SO_RCVTIMEO和SO_SNDTIMEO

SIGALRM信号 


网络程序需要处理的第三类事件是定时事件,比如定期检测一个客户连接的活动状态。服务器程序通常管理着众多定时事件,因此有效地组织这些定时事件,使之能在预期的时间点被触发且不影响服务器的主要逻辑,对于服务器的性能有着至关重要的影响。为此,我们要将每个定时事件分别封装成定时器,并使用某种容器类数据结构,比如链表、排序链表和时间轮,将所有定时器串联起来,以实现对定时事件的统一管理。主要讨论的就是两种高效的管理定时器的容器:时间轮和时间堆。

Linux提供了三种定时方法:

  • socket选项SO_RCVTIMEO和SO_SNDTIMEO。
  • SIGALRM信号。
  • I/O复用系统调用的超时参数。

socket选项SO_RCVTIMEO和SO_SNDTIMEO

这两个选项仅对于数据接收和发送相关的socket专用系统调用有效,这些系统调用包括send、sendmsg、recv、recvmsg、accept和connect。选项SO_RCVTIMEO和SO_SNDTIMEO对这些系统调用的影响总结于表中:

系统调用有效选项系统调用超时后的行为
sendSO_SNDTIMEO返回-1,设置errno为EAGAIN或EWOULDBLOCK
sendmsgSO_SNDTIMEO返回-1,设置errno为EAGAIN或EWOULDBLOCK
recvSO_RCVTIMEO返回-1,设置errno为EAGAIN或EWOULDBLOCK
recvmsgSO_RCVTIMEO返回-1,设置errno为EAGAIN或EWOULDBLOCK
acceptSO_RCVTIMEO返回-1,设置errno为EAGAIN或EWOULDBLOCK
connectSO_SNDTIMEO返回-1,设置errno为EINPROGRESS

由表可见,在程序中,我们可以根据系统调用(send、sendmsg、recv、recvmsg、accept和connect)的返回值以及errno来判断超时时间是否已到,进而决定是否开始处理定时任务。

SIGALRM信号 

第10章提到,由alarm和settimer函数设置的实时闹钟一旦超时,将触发SIGALRM信号。因此我们可以利用该信号的信号处理函数来处理定时任务。但是,如果要处理多个定时任务,我们就需要不断地触发SIGALRM信号,并在其信号处理函数中执行到期的任务。一般而言,SIGALRM信号按照固定的频率生成,即由alarm或settimer函数设置的定时周期T保持不变。如果某个定时任务的超时函数不是T的整数倍,那么它实际被执行的时间和预期的时间将略有误差。因此定时周期T反映了定时的精度。

本节中我们通过一个实例——处理非活动连接,来介绍如何使用SIGALRM信号定时。不过,我们需要先给出一种简单的定时器实现——基于升序链表的定时器,并把他应用到处理非活动连接这个实例中。这样,我们才能观察到SIGALRM信号处理函数是如何处理定时器并执行定时任务的。此外,我们介绍这种定时器也是为了和后面要讨论的高效定时器——时间轮和时间堆做对比。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值