精确定时器设置(《精通Unix下C语言编程与项目实践》之六)

文章试读
不拘一个遍程序系列:编程序不能一个脑袋钻到底,有时要学会变通,即所谓的曲线救国。一、二、三、四
职场规划:一些杂七杂八的职场感悟吧。不值钱的软件人才 精力充沛与事业成功   让系分来得更猛烈些吧    不值钱的系统分析师 
我的诗歌:都是我的打油诗,但是很值得一读。不要工作还衣食无忧之四难歌   香格里拉美人图
宝宝图片:超可爱的小宝宝 写博客
考试培训:主要是关于考研、软考和等级的相关题解。2009考研试题分析   2008年12月程序员试题分析    2009年软考备考全攻略    2008年5月程序员试题解析
 
 
 
《精通Unix下C语言编程与项目实践》之六
精确定时器设置 
作者:朱云翔,胡平
 

10.5.2 精通定时器设置

函数 alarm 设置的定时器只能精确到秒,而以下函数理论上可以精确到微妙:
#include  <sys/select.h>
#include  <sys/itimer.h>
int getitimer(int which, struct itimerval *value);
int setitimer(int which, const struct itimerval *value, struct itimerval *ovalue);
函数 setitimer 可以提供三种定时器,它们相互独立,任意一个定时完成都将发送定时信号到进程,并且自动重新计时。参数 which 确定了定时器的类型,如表 10-6 所示:
10-6 参数 which 与定时器类型
取值
含义
信号发送
ITIMER_REAL
定时真实时间,与 alarm 类型相同。
SIGALRM
ITIMER_VIRT
定时进程在用户态下的实际执行时间。
SIGVTALRM
ITIMER_PROF
定时进程在用户态和核心态下的实际执行时间。
SIGPROF
这三种定时器定时完成时给进程发送的信号各不相同,其中 ITIMER_REAL 类定时器发送 SIGALRM 信号, ITIMER_VIRT 类定时器发送 SIGVTALRM 信号, ITIMER_REAL 类定时器发送 SIGPROF 信号。
函数 alarm 本质上设置的是低精确、非重载的 ITIMER_REAL 类定时器,它只能精确到秒,并且每次设置只能产生一次定时。函数 setitimer 设置的定时器则不同,它们不但可以计时到微妙(理论上),还能自动循环定时。在一个 Unix 进程中,不能同时使用 alarm ITIMER_REAL 类定时器。
结构 itimerval 描述了定时器的组成:
struct itimerval
{
    struct tim.  it_interval;     /* 下次定时取值 */
    struct tim.  it_value;        /* 本次定时设置值 */
}
    结构 tim. 描述了一个精确到微妙的时间:
struct tim.
{
    long    tv_sec;                 /* 秒( 1000000 微秒) */
    long    tv_usec;                 /* 微妙 */
}
函数 setitimer 设置一个定时器,参数 value 指向一个 itimerval 结构,该结构决定了设置的定时器信息,结构成员 it_value 指定首次定时的时间,结构成员 it_interval 指定下次定时的时间。定时器工作时,先将 it_value 的时间值减到 0 ,发送一个信号,再将 it_value 赋值为 it_interval 的值,重新开始定时,如此反复。如果 it_value 值被设置为 0 ,则定时器停止定时;如果 it_value 值不为 0 it_interval 值为 0 ,则定时器在一次定时后终止。
函数 setitimer 调用成功时返回 0 ,否则返回 -1 ,参数 ovalue 如果不为空,返回上次的定时器状态。
函数 getitimer 获取当前的定时器状态,整型参数 which 指定了读取的定时器类型,参数 value 返回定时器状态。函数调用成功返回 0 ,否则返回 -1
1. 设置一个定时器,每 2.5 秒产生一个 SIGALRM 信号。
答:将 itimerval 结构的成员 it_interval 和成员 it_value 均赋值为 2.5 秒即可:
struct itimerval value;
value.it_value.tv_sec=2;
value.it_value.tv_usec=500000;
value.it_interval.tv_sec=2;
value.it_interval.tv_usec=500000;
setitimer(ITIMER_REAL, &value, NULL);
函数 setitimer 设置的定时器可以重复定时,无需多次调用。
2. 设置一个定时器,进程在用户态下执行 1 秒钟后发出首次信号,以后进程每在用户态下执行 3 秒钟,发送一个信号。
答:将 itimerval 结构的成员 it_value 均赋值为 1 秒,成员 it_interval 赋值为 3 秒即可:
struct itimerval value;
value.it_value.tv_sec=1;
value.it_value.tv_usec=0;
value.it_interval.tv_sec=3;
value.it_interval.tv_usec=0;
setitimer(ITIMER_VIRT, &value, NULL);
3. 取消一个 ITIMER_PROF 类定时器。
itimerval 结构的成员 it_value 均赋值为 0 秒即可
struct itimerval value;
value.it_value.tv_sec=1;
value.it_value.tv_usec=0;
setitimer(ITIMER_PROF, &value, NULL);
4. 设置一个定时 1.5 秒的真实时间定时器,它仅发送一次信号就自动取消。
答:将 itimerval 结构的成员 it_value 均赋值为 1.5 秒,成员 it_interval 赋值为 0 秒即可:
struct itimerval value;
value.it_value.tv_sec=1;
value.it_value.tv_usec=500000;
value.it_interval.tv_sec=0;
value.it_interval.tv_usec=0;
setitimer(ITIMER_REAL, &value, NULL);

精确定时器实例

本处设计了一个精确定时器的例子,进程每隔 1.5 秒数发送定时信号 SIGPROF ,在接收到信号时将打印定时的次数,用户可以键入 CTRL_C DELETE 结束程序,如代码 10-11 所示:
代码 10-11 精确定时器实例(节自 /code/chapter10/time4.c
#include  <sys/select.h>
#include  <sys/itimer.h>
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
int n = 0;
void timefunc(int sig)                      /* 定时事件代码 */
{
    fprintf(stderr, "ITIMER_PROF[%d]\n", n++);
    signal(SIGPROF, timefunc);              /* 捕获定时信号 */
}
void main()
{
    struct itimerval value;
    value.it_value.tv_sec=1;                /* 定时 1.5 */
    value.it_value.tv_usec=500000;
    value.it_interval.tv_sec=1;             /* 定时 1.5 */
    value.it_interval.tv_usec=500000;
    signal(SIGPROF, timefunc);          /* 捕获定时信号 */
    setitimer(ITIMER_PROF, &value, NULL);   /* 定时开始 */
    while (1);
}
编译和运行代码 10-11
# make time4
        cc -O -o time4 time4.c
# ./time4
ITIMER_PROF[0]
ITIMER_PROF[1]
ITIMER_PROF[2]
ITIMER_PROF[3]
 
 
  相关文章:
封面          前言        目录         策划         作者
动态库        变长参数    文件锁       外设         僵死进程
定时器 
 

你可能感兴趣的:(c,定时器,C语言编程,Unix编程)