我们常常有设置系统在某一时间执行相应动作的需求,比如设置电脑什么时候自动锁屏,什么时候自动关机,设置应用程序什么时候自动运行,什么时候自动退出。这些与时间相关的功能,都需要依靠操作系统中的定时器来实现。

  linux中定时器的使用原理很简单,你只需设置一个超时时间和相应的执行函数,系统就会在超时的时候执行一开始设置的函数。超时的概念有点模糊,它指的是你设定一个时间,如果当前的时间超过了你设定的时间,那就超时了。比如说,你设置五分钟后系统自动关机,系统会记住五分钟后的具体时间,也就是当前时间再加上五分钟。过了五分钟后,系统当前时间已经比刚才设置的具体时间大了,出现超时,于是运行超时行为。

  在linux中,使用alarm函数可以设置一个定时器,当定时器超时的时候,会产生SIGALRM信号。因此,要设置超时行为,就得在SIGALRM信号上设置相应的函数。

  包含头文件:#include <unistd.h>

  函数原型:unsigned int alarm(unsigned int seconds);

  具体例子如下:  

#include <stdio.h>
#include <signal.h>
#include <unistd.h> void SigFun(int signo){
printf("SigFun is running\n");
} int main(){
if(signal(SIGALRM, SigFun) == SIG_ERR){
perror("signal\n");
     return -1;
}
alarm();
pause();
}

  在linux中,一个进程只能有一个定时器,因此当一个进程需要设置多个定时行为时,需要采取相应的措施,使得一个定时器可以实现多个定时。主要的方法有两种,一种叫时间链,一种叫时间堆。

  时间链是将所有定时行为以链表的方式连在一起,同时在进程中维护一个固定时间超时的定时器。当定时器超时的时候,检查链表上所有的行为是否超时,如果有超时的行为,则运行其行为,并将其从链表中删除。这用方法最大的坏处就是需要固定时间遍历整个链表,造成了比较大的开销。

  时间堆是将所有定时行为以最小堆的方式组织起来,并且在进程中维护一个以堆顶为超时时间的定时器。当定时器超时时,检查堆顶行为是否超时,如果超时,则运行该行为,并将其从堆顶删除,接着继续检查;如果堆顶行为未超时,则用其超时时间继续设置定时器。时间堆不用固定时间去检查所有定时行为,只需在超时的时候运行相应的超时行为,效率比时间链高。

  在linux中,alarm函数是以秒计时的,当有时我们需要更小的时间单位去设置行为,比如毫秒,应该怎么办呢?linux提供setitimer函数,可以提供更精确的定时器。

  包含头文件:#include <sys/time.h>

  函数原型:int setitimer(int which, const struct itimerval *new_value, struct itimerval *old_value);

  参数:

  int which有三种选择:

  ITIMER_REAL:decrements in real time, and deliversSIGALRM upon expiration.

  ITIMER_VIRTUAL:decrements only  when  the  process  is  executing,  anddeliversSIGVTALRM upon expiration.

  ITIMER_PROF:decrements  both  when the process executes and when the system is executing on behalf of the  process. Coupledwith  ITIMER_VIRTUAL, this timer is usually used to profile the time spent by the application in user and  kernel space.  SIGPROF is delivered

  const struct itimerval *new_value的数据结构如下:

struct itimerval {
struct timeval it_interval; /* 第一次超时以后每次超时的时间 */
struct timeval it_value; /* 第一次超时的时间 */
};
struct timeval {
long tv_sec; /* seconds */
long tv_usec; /* microseconds */
};

  struct itimerval *old_value是原来设置的时间,如果不需要用到,可以用NULL

  成功调用返回0,失败返回-1。

  具体例子如下:

#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <sys/time.h> void SigFun(int signo){
printf("SigFun is running\n");
} int main(){
if(signal(SIGALRM, SigFun) == SIG_ERR){
perror("signal\n");
return -;
} struct itimerval tv;
tv.it_value.tv_usec = ;
tv.it_value.tv_sec = ;
tv.it_interval.tv_usec = ;
tv.it_interval.tv_sec = ; if(setitimer(ITIMER_REAL, &tv, NULL) != ){
perror("setitimer\n");
return -;
} while(true){
pause();
}
}

linux定时器的更多相关文章

  1. linux定时器用法

    linux定时器  原文出自http://www.cnblogs.com/processakai/archive/2012/04/11/2442294.html 今天看书看到了关于alarm的一些用法 ...

  2. linux定时器crontab

    linux定时器crontab用法: 1.基本格式 : * * * * * command 分 时 日 月 周 命令 第1列表示分钟1-59 每分钟用*或者 */1表示 第2列表示小时1-23(0表示 ...

  3. Linux 定时器应用【转】

    Linux 定时器应用 实验目的 阅读 Linux 相关源代码,学习 Linux 系统中的时钟和定时器原理,即,ITIMER_REAL实时计数,ITIMER_VIRTUAL 统计进程在用户模式执行的时 ...

  4. 4412 Linux定时器

    一.Linux定时器基础知识 1.1 定时器的使用范围 延后执行某个操作,定时查询某个状态:前提是对时间要求不高的地方 1.2 内核时间概念 Hz:(系统时钟通过CONFIG_HZ来设置,范围是100 ...

  5. linux定时器(crontab)实例

    linux实验示例----实现每2分钟将“/etc”下面的文件打包存储到“/usr/lobal”目录下 ·Step1:编辑当前用户的crontab并保存终端输入:>crontab -u root ...

  6. Linux定时器相关源码分析

    Linux的定时器使用时间轮算法.数据结构不难理解,核心数据结构与散列表及其相似,甚至可以说,就是散列表.事实上,理解其散列表的本质,有助于对相关操作的理解. 数据结构 这里先列出一些宏,稍后解释: ...

  7. Smart210学习记录-----linux定时器

    1.内核定时器: Linux 内核所提供的用于操作定时器的数据结构和函数如下: (1) timer_list 在 Linux 内核中,timer_list 结构体的一个实例对应一个定时器 1 stru ...

  8. linux 定时器编程实例(完善中).....

    最近在写linux 下的定时器编程实验,测试发现 usleep函数在 x86 架构下的定时还是比较准确的,在arm9下 就不太准了. 今天用linux 下的setitimer()函数进行了定时 器的测 ...

  9. linux定时器HZ和Jiffies

    1.linux HZ Linux核心几个重要跟时间有关的名词或变数,以下将介绍HZ.tick与jiffies. HZ Linux核心每隔固定周期会发出timer interrupt (IRQ 0),H ...

随机推荐

  1. DSP知识

    自己认为是问题的问题,时常更新,为了记录学习的点点滴滴. 1.什么是boot loader ? DSP 的速度尽快,EPROM 或flash 的速度较慢, 而DSP 片内的RAM很快, 片外的RAM也 ...

  2. iOS 多线程学习笔记 —— NSThread

    本文复制.参考自文章:iOS多线程编程之NSThread的使用  ,主要为了加强个人对知识的理解和记忆,不做他用.原作者声明: 著作权声明:本文由http://blog.csdn.net/totogo ...

  3. Ubuntu14.04 安装配置Hadoop2.6.0

    目前关于Hadoop的安装配置教程书上.官方教程.博客都有很多,但由于对Linux环境的不熟悉以及各种教程或多或少有这样那样的坑,很容易导致折腾许久都安装不成功(本人就是受害人之一).经过几天不断尝试 ...

  4. ContentProvider初阶Cookbook

    在Android世界里,ContentProvider将数据存储抽象成了类似SQL的形式,通过insert, delete, update, query等接口实现对数据的增删改查.通过ContentP ...

  5. 29. Divide Two Integers

    用加减法模拟除法. 除法本质就是 被除数 - 商个除数相加 = 0 如果你电脑足够好,可以无限减..但是这个题肯定不是这么简单. 最快的方法还是 减去 商乘以除数. 但是这里不能使用乘法,那只好用BI ...

  6. thinkphp xml编码函数

    /** * XML编码 * @param mixed $data 数据 * @param string $root 根节点名 * @param string $item 数字索引的子节点名 * @pa ...

  7. UVaLive2572 poj1418 UVa1308 Viva Confetti

    一次放下n个圆 问最终可见的圆的数量 应该是比较经典的问题吧 考虑一个圆与其他每个圆的交点O(n)个 将其割成了O(n)条弧 那么看每条弧的中点 分别向内向外调动eps这个点 则最上面的覆盖这个点的圆 ...

  8. UVa1608 UVaLive6258 Non-boring sequences

    填坑系列(p.248) 比较神 从两端枚举 最坏复杂度就成O(nlogn)了 #include<cstdio> #include<cstdlib> #include<al ...

  9. 移植QT到ZedBoard(制作运行库镜像) 交叉编译 分类: ubuntu shell ZedBoard OpenCV 2014-11-08 18:49 219人阅读 评论(0) 收藏

    制作运行库 由于ubuntu的Qt运行库在/usr/local/Trolltech/Qt-4.7.3/下,由makefile可以看到引用运行库是 INCPATH = -I/usr//mkspecs/d ...

  10. 常用mimetype

    $mimetypelist["csm"] = "application/cu-seeme";$mimetypelist["cu"] = &q ...