文章试读
|
不拘一个遍程序系列:编程序不能一个脑袋钻到底,有时要学会变通,即所谓的曲线救国。一、二、三、四
职场规划:一些杂七杂八的职场感悟吧。不值钱的软件人才 精力充沛与事业成功 让系分来得更猛烈些吧 不值钱的系统分析师
我的诗歌:都是我的打油诗,但是很值得一读。不要工作还衣食无忧之四难歌 香格里拉美人图
宝宝图片:超可爱的小宝宝 写博客
考试培训:主要是关于考研、软考和等级的相关题解。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]
相关文章:
封面 前言 目录 策划 作者
动态库 变长参数 文件锁 外设 僵死进程
定时器