Linux-定时器

本文介绍了Linux下三种定时机制:socket选项SO_RCVTIMEO和SO_SNDTIMEO用于设置socket收发超时;SIGALRM通过alarm和settimer函数设置实时闹钟;I/O复用系统调用的超时参数则用于轮询操作。文章还提供了具体的代码实例。
摘要由CSDN通过智能技术生成


定时是指一段时间后触发某段代码的机制,Linux提供了以下三种定时方法:

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

socket选项SO_RCVTIMEO和SO_SNDTIMEO

分别用来设置socket接收数据超时时间和发送数据超时时间,所以用于与socket数据收发有关的系统调用,如send,recv,sendmsg,recvmsg,accept,connect等。
在这里插入图片描述

example,connect超时

int timeout_connect(const char* ip, int port, int time{
	/* 
	初始化socket参数
	*/
	int sockfd = socket(AF_INET, SOCK_STREAM, 0);
	struct timeval timeout;
	timeout.tv_sec = time;
	timeout.tv_usec = 0;
	socklen_t len = sizeof(timeout);
	ret = setsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO, &timeout, len);
	assert(ret != -1);
	ret = connect(sockfd, (sockaddr*)&addr, sizeof(addr));
	if(ret == -1){
		
		if(errno == EINPROGRESS){
			// connect系统调用超时了,处理定时任务
			return -1;
		}
		// 连接到server时的错误
		return -1;
	}
}

int main(){
	int sockfd = timeout_connect(ip, port, time);
	if(sockfd < 0){
		return -1;
	}
}

SIGALRM

由alarm和settimer函数设置的实时闹钟一旦超时,就会触发SIGALRM信号。

基于升序链表的定时器

定时器通常包含超时时间和任务回调函数。有时还含有回调函数的参数和是否重启定时器的信息。
原文中使用了双向链表,但没有使用头尾节点,编程实现繁琐,这里给出带头尾节点的实现方法:
Cpp实现

处理非活动连接

服务器通常需要定期处理非活动连接,给客户端发送重连请求或关闭连接。
Linux内核中提供了socket的KEEPALIVE选项来定期检查连接是否处于活动状态的定期检查机制。
但是这种机制使得应用程序对于连接的管理变得复杂,我们可以在应用层来实现类似的机制。

一下代码利用alarm函数周期性触发SIGALRM信号,该信号的信号处理函数利用管道通知主循环执行定时器链表上的定时任务——关闭非活动的连接。
代码实现链接

IO复用系统调用的超时参数

因为I/O复用可能在超时时间到期之前就返回(有就绪事件发生),所以如果需要使用I/O复用的超时的话,需要不断更新定时参数以反映剩余时间。

const int TIMEOUT = 5000;
int timeout = TIMEOUT;
time_t start = time(NULL);
time_t end = time(NULL);

while(true){
	printf("The timeout is now %d mil-seconds\n", timeout);
	start = time(NULL);
	int number = epoll_wait(epollfd, events, MAX_NUM, timeout);
	if(number < 0){
		// error
		break;
	}
	else if(number == 0){
		// 说明epoll_wait超时时间到了,此时可处理定时任务,并重置定时时间
		timeout = TIMEOUT;
		continue;
	}
	end = time(NULL);
	// 如果epoll_wait的返回值大于0,则本次调用的持续时间是
	// (end - start) * 1000 ms, 我们需要处理一下
	timeout = timeout - (end - start) * 1000;
	if(timeout <= 0){
		timeout = TIMEOUT;
	}
	// handle connections;
}

高性能定时器

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值