linux 用户空间 定时器,用户态定时器介绍

本文为作者原创,可以自由拷贝,转载。但转载请保持文档的完整性,注明原作者及原链接,严禁用于任何商业用途。

作者:misteryoung

博客:http://blog.chinaunix.net/uid/20706239

=======================================================================

1 前言

在很多用户态程序使用select实现定时器的功能。因为该函数既可以实现fd的多路复用,又可以实现超时的功能,可谓功能强大。那么Linux有没有给用户态提供标准的定时器接口呢?答案当然是:有。

下面介绍几个标准的用户态定时器。讲解内容包括:

1)原理及用法;

2)实现细节(包括用户态及内核态),因为涉及系统调用,因此内核部分比较多;

3)本文只介绍3个定时器:alarm、setitimer、timer_create

2 alarm定时器

alarm函数大家应该并不陌生,在busybox版的ping源码中就使用了该函数,用以实现超时功能。

其函数原型及man中的帮助信息如下所示:

点击(此处)折叠或打开

unsigned int alarm(unsigned int seconds);

DESCRIPTION

alarm() arranges for a SIGALRM signal to be delivered to the calling process in seconds seconds.

If seconds is zero, no new alarm() is scheduled.

In any event any previously set alarm() is canceled.

RETURN VALUE

alarm() returns the number of seconds remaining until any previously scheduled alarm was due to be delivered, or zero if there was no previously scheduled alarm.

2.1 原理

简单来说,其功能实现包含两部分:

1)注册SIGALRM信号处理函数;

2)通过alarm设置超时时间(单位为秒),超时后信号处理函数被执行;

alarm(seconds)代表设置新的定时器,并覆盖老的定时器(如果有的话)。若取消已有定时器可执行alarm(0)。

2.2 用法

1)signal(SIGALRM, alarm_func)

2)alarm(expire)

expire秒后alarm_func函数被执行。

2.3 alarm跟踪

我们都知道,alarm通过系统调用陷入到内核态,内核对应的函数为sys_alarm。

点击(此处)折叠或打开

SYSCALL_DEFINE1(alarm, unsigned int, seconds)

{

return alarm_setitimer(seconds);

}

上面代码展开后如下所示:

sys_alarm(unsigned intseconds)

{

return alarm_setitimer(seconds);

}

继续跟踪alarm_setitimer:

点击(此处)折叠或打开

unsigned int alarm_setitimer(unsigned int seconds)

{

struct itimerval it_new, it_old;

#if BITS_PER_LONG < 64

if (seconds > INT_MAX)

seconds = INT_MAX;

#endif

it_new.it_value.tv_sec = seconds;    时间初始化

it_new.it_value.tv_usec = 0;

it_new.it_interval.tv_sec = it_new.it_interval.tv_usec = 0;

do_setitimer(ITIMER_REAL, &it_new, &it_old); 设置新的超时时间,并获取老的剩余的超时时间

/*

* We can't return 0 if we have an alarm pending ... And we'd

* better return too much than too little anyway

*/

if ((!it_old.it_value.tv_sec && it_old.it_value.tv_usec) ||

it_old.it_value.tv_usec >= 500000)

it_old.it_value.tv_sec++;

return it_old.it_value.tv_sec;    返回老的剩余的超时时间

}

继续跟踪do_setitimer

点击(此处)折叠或打开

int do_setitimer(int which, struct itimerval *value, struct itimerval *ovalue)

{

struct task_struct *tsk = current;

struct hrtime

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值