linux定时器

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

  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(5);
    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 -1;
    }

    struct itimerval tv;
    tv.it_value.tv_usec = 500000;
    tv.it_value.tv_sec = 0;
    tv.it_interval.tv_usec = 300000;
    tv.it_interval.tv_sec = 0;

    if(setitimer(ITIMER_REAL, &tv, NULL) != 0){
        perror("setitimer\n");
        return -1;
    }

    while(true){
        pause();
    }
}
时间: 2024-11-08 13:27:00

linux定时器的相关文章

【转】Linux 定时器setitimer()

http://blog.sina.com.cn/s/blog_590be5290100izdf.html 用法: #include <sys/time.h> int getitimer(int which, struct itimerval *value); int setitimer(int which, const struct itimerval *value, struct itimerval *ovalue); 功能描述: 获取或设定间歇计时器的值.系统为进程提供三种类型的计时器,每

Linux 定时器

也许,一本书你从头到尾都看完了,但也只是看完了. 也许,你似懂非懂的理解了. 但,当你准备用学来的这些东西做东西时,才发现:原来你根本没懂! 看书重要的不是看了多少,重要的是理解了多少,理解的多深多广! 一个傅里叶变换,一个小波,我怎么越看越晕? "学以致用"这四个字越来越被教育所忽视了. 如果不是图像处理我真不知道线性代数原来可以这么牛逼! ......................................... #include <stdio.h> #incl

Linux定时器接口

Linux定时器接口主要分为三类: 一. sleep(), unsleep, alarm(),引用了SIGALARM信号,在多线程中使用信号又是相当麻烦的. 二. nanosleep(), clock_nanosleep(),让线程挂起,程序失去响应,多线程网络编程中应该避免. 三. timerfd_create(),也是用信号来deliver超时,将时间转变成一个文件描述符,可以像其他I/O事件一样操作定时器,所以程序中在写I/O框架用到定时器首选timerfd_create(). 1. ti

Linux定时器 使用

1.alarm alarm()执行后,进程将继续执行,在后期(alarm以后)的执行过程中将会在seconds秒后收到信号SIGALRM并执行其处理函数. #include <stdio.h>#include <unistd.h>#include <signal.h>void sigalrm_fn(int sig){    printf("alarm!\n");    alarm(2);    return;}int main(void){    s

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

1.内核定时器: Linux 内核所提供的用于操作定时器的数据结构和函数如下: (1) timer_list 在 Linux 内核中,timer_list 结构体的一个实例对应一个定时器 1 struct timer_list { 2    struct list_head entry; /* 定时器列表 */ 3    unsigned long expires; /*定时器到期时间*/ 4    void (*function)(unsigned long); /* 定时器处理函数 */ 5

Linux定时器工具-crontab 各參数具体解释及怎样查看日志记录

要使用crontab定时器工具,必需要启动cron服务: service cron start crontab的语法,以备日后救急.先上张超给力的图: crontab各參数说明: -e : 运行文字编辑器来编辑crontab,内定的文字编辑器是VI -r : 删除眼下的crontab -l : 列出眼下的crontab(查看专用) -i : 会和-r 配合使用,在删除当前的crontab时询问,输入y 则删除 注意crontab是分用户的,以谁登录就会编辑到谁的crontab crontab特殊

linux定时器(crontab)实例

linux实验示例----实现每2分钟将“/etc”下面的文件打包存储到“/usr/lobal”目录下 ·Step1:编辑当前用户的crontab并保存终端输入:>crontab -u root -l #查看root用户设置的定时器>crontab -u root -e #进入vi编译模式 00-59/2 * * * * /bin/bash /usr/local/crontab_test.sh #Esc退出编辑模式,在文件尾部输入“:wq”进行保存 ·Step2:/usr/local目录下,编

linux定时器的实现方法

Linux提供定时器机制,可以指定在未来的某个时刻发生某个事件,定时器的结构如下: struct timer_list { struct list_head list; unsigned long expires; unsigned long data; void (*function)(unsigned long); }; list 实现的时候使用的,和定时器功能无关expires 是定时器定时的滴答数(当前的滴答数为 jiffies )function 到那个时刻内核调用的函数data 由于

Linux定时器的实现

http://www.ibm.com/developerworks/cn/linux/l-cn-timers/ http://blog.csdn.net/zhangxinrun/article/details/5914191