当前位置: 技术问答>linux和unix
C语言怎么实现定时器
来源: 互联网 发布时间:2016-07-02
本文导语: C语言怎么实现定时器 比如我现在要3分钟执行一次我的函数 怎么做。 | Linux下的定时器:alarm()与setitimer() http://blog.csdn.net/feiyinziiuxx/archive/2009/08/26/4488140.aspx | // init timer ...
C语言怎么实现定时器 比如我现在要3分钟执行一次我的函数 怎么做。
|
Linux下的定时器:alarm()与setitimer()
http://blog.csdn.net/feiyinziiuxx/archive/2009/08/26/4488140.aspx
http://blog.csdn.net/feiyinziiuxx/archive/2009/08/26/4488140.aspx
|
// init timer
void TimerFactory::init_timer()
{
struct itimerval value;
value.it_value.tv_sec = 1; // min interval 1 second
value.it_value.tv_usec = 0;
value.it_interval = value.it_value;
Setitimer(ITIMER_REAL, &value, NULL );
return;
}
// init signal
void TimerFactory::init_signal()
{
Signal(SIGALRM, on_alarm);
return;
}
// callback to do things when SIGALARM arrived
void TimerFactory::on_alarm(int signo)
{
// do things you like here.
return;
}
|
如果是c++,可以参考这个,里面有一个现成的类,或者用boost::asio库
http://stackoverflow.com/questions/503866/timer-class-in-linux
http://stackoverflow.com/questions/503866/timer-class-in-linux
|
SIGPIPE 是一种由软件条件产生的信号,在例 3.7 “管道”中已经介绍过了。
本节主要介绍 alarm 函数和 SIGALRM 信号。
#include
unsigned int alarm(unsigned int seconds);
调用 alarm 函数可以设定一个闹钟,也就是告诉内核在 seconds 秒之后给当前
进程发 SIGALRM 信号,该信号的默认处理动作是终止当前进程。这个函数的返
回值是 0 或者是以前设定的闹钟时间还余下的秒数。打个比方,某人要小睡一
觉,设定闹钟为 30 分钟之后响,20 分钟后被人吵醒了,还想多睡一会儿,于
是重新设定闹钟为 15 分钟之后响,“以前设定的闹钟时间还余下的时间”就是
10 分钟。如果 seconds 值为 0,表示取消以前设定的闹钟,函数的返回值仍然
是以前设定的闹钟时间还余下的秒数。
例 6.1. alarm
#include
#include
int main(void)
{
int counter;
alarm(1);
for(counter=0; 1; counter++)
printf("counter=%d ", counter);
return 0;
}
这个程序的作用是 1 秒钟之内不停地数数,1 秒钟到了就被 SIGALRM 信号终
止。
本节主要介绍 alarm 函数和 SIGALRM 信号。
#include
unsigned int alarm(unsigned int seconds);
调用 alarm 函数可以设定一个闹钟,也就是告诉内核在 seconds 秒之后给当前
进程发 SIGALRM 信号,该信号的默认处理动作是终止当前进程。这个函数的返
回值是 0 或者是以前设定的闹钟时间还余下的秒数。打个比方,某人要小睡一
觉,设定闹钟为 30 分钟之后响,20 分钟后被人吵醒了,还想多睡一会儿,于
是重新设定闹钟为 15 分钟之后响,“以前设定的闹钟时间还余下的时间”就是
10 分钟。如果 seconds 值为 0,表示取消以前设定的闹钟,函数的返回值仍然
是以前设定的闹钟时间还余下的秒数。
例 6.1. alarm
#include
#include
int main(void)
{
int counter;
alarm(1);
for(counter=0; 1; counter++)
printf("counter=%d ", counter);
return 0;
}
这个程序的作用是 1 秒钟之内不停地数数,1 秒钟到了就被 SIGALRM 信号终
止。
|
网上找到的, 我整理了一下:
使用定时器的目的无非是为了周期性的执行某一任务, 或者是到了一个指定时间去执行某一任务. 要达到这一目的, 一般有两个常见的比较有效的方法. 一个是用Linux内部的三个定时器, 另一个是用sleep, usleep函数让进程睡眠一段时间, 其实还有一个方法, 那就是用gettimeofday, difftime等自己来计算时间间隔, 然后时间到了就执行某一任务, 但这种方法效率低, 所以不常用.
Linux 为每个进程提供的3个内部计时器:
ITIMER_REAL: 给一个指定的时间间隔, 按照实际的时间来减少这个计数, 当时间间隔为0的时候发出SIGALRM信号.
ITIMER_VIRTUAL: 给定一个时间间隔, 当进程执行的时候才减少计数, 时间间隔为0的时候发出SIGVTALRM信号.
ITIMER_PROF: 给定一个时间间隔, 当进程执行或者是系统为进程调度的时候, 减少计数, 时间到了, 发出SIGPROF信号, 这个和ITIMER_VIRTVAL联合, 常用来计算系统内核时间和用户时间.
常用到的函数:
#include
int getitimer (int which, struct itimerval* value);
int setitimer (int which, struct itimerval* newvalue, struct itimerval* oldvalue);
struct timeval
{
long tv_sec; /* 秒 */
long tv_usec; /* 微秒 */
};
struct itimerval
{
struct timeval it_interval; /* 时间间隔 */
struct timeval it_value; /* 当前时间计数 */
};
it_interval用来指定每隔多长时间执行任务, it_value用来保存当前时间离执行任务还有多长时间. 比如说, 你指定it_interval为2秒(微秒为0), 开始的时候我们把it_value的时间也设定为2秒(微秒为0), 当过了一秒, it_value就减少一个为1, 再过1秒, 则it_value又减少1, 变为0, 这个时候发出信号(告诉用户时间到了, 可以执行任务了), 并且系统自动把it_value的置重置为it_interval的值, 即2秒, 再重新计数.
使用定时器的目的无非是为了周期性的执行某一任务, 或者是到了一个指定时间去执行某一任务. 要达到这一目的, 一般有两个常见的比较有效的方法. 一个是用Linux内部的三个定时器, 另一个是用sleep, usleep函数让进程睡眠一段时间, 其实还有一个方法, 那就是用gettimeofday, difftime等自己来计算时间间隔, 然后时间到了就执行某一任务, 但这种方法效率低, 所以不常用.
Linux 为每个进程提供的3个内部计时器:
ITIMER_REAL: 给一个指定的时间间隔, 按照实际的时间来减少这个计数, 当时间间隔为0的时候发出SIGALRM信号.
ITIMER_VIRTUAL: 给定一个时间间隔, 当进程执行的时候才减少计数, 时间间隔为0的时候发出SIGVTALRM信号.
ITIMER_PROF: 给定一个时间间隔, 当进程执行或者是系统为进程调度的时候, 减少计数, 时间到了, 发出SIGPROF信号, 这个和ITIMER_VIRTVAL联合, 常用来计算系统内核时间和用户时间.
常用到的函数:
#include
int getitimer (int which, struct itimerval* value);
int setitimer (int which, struct itimerval* newvalue, struct itimerval* oldvalue);
struct timeval
{
long tv_sec; /* 秒 */
long tv_usec; /* 微秒 */
};
struct itimerval
{
struct timeval it_interval; /* 时间间隔 */
struct timeval it_value; /* 当前时间计数 */
};
it_interval用来指定每隔多长时间执行任务, it_value用来保存当前时间离执行任务还有多长时间. 比如说, 你指定it_interval为2秒(微秒为0), 开始的时候我们把it_value的时间也设定为2秒(微秒为0), 当过了一秒, it_value就减少一个为1, 再过1秒, 则it_value又减少1, 变为0, 这个时候发出信号(告诉用户时间到了, 可以执行任务了), 并且系统自动把it_value的置重置为it_interval的值, 即2秒, 再重新计数.
|
一种不可移植的方法是调用sleep(),一种可移植但不优雅的方法是:
/* 前文再续 */
调用gettimeofday()取得此刻的时间
while(1)
{
调用gettimeofday()取得此刻的时间
if(两个时间差满足你的要求) break;
}
/* 书接下一回 */
/* 前文再续 */
调用gettimeofday()取得此刻的时间
while(1)
{
调用gettimeofday()取得此刻的时间
if(两个时间差满足你的要求) break;
}
/* 书接下一回 */
|
不推荐使用 有时候会导致CPU利用率老高了
用1楼说的alarm()与setitimer()
具体用法google一下 写个简单的代码练习一下就会了
|
这个玩意就是一种无奈,很多时候都要在可移植性和效率中作二选一。
|
你可以直接调用alarm。
其本质就是计时加上信号触发。
此外,select计时更精确,虽然不是专门用来计时的
其本质就是计时加上信号触发。
此外,select计时更精确,虽然不是专门用来计时的
|
很精辟!
|
学习
|
mark