我需要每秒调用一个函数,因为我想根据每秒存储数据,所以我不能错过第二个?什么是C的最佳方法?
下面是timer_create方法的骨架,这个可靠吗?
#include <stdio.h>
#include <time.h>
#include <signal.h>
timer_t gTimerid;
void start_timer(void)
{
struct itimerspec value;
value.it_value.tv_sec = 1;
value.it_value.tv_nsec = 0;
value.it_interval.tv_sec = 1;
value.it_interval.tv_nsec = 0;
timer_create (CLOCK_REALTIME, NULL, &gTimerid);
timer_settime (gTimerid, 0, &value, NULL);
}
void stop_timer(void)
{
struct itimerspec value;
value.it_value.tv_sec = 0;
value.it_value.tv_nsec = 0;
value.it_interval.tv_sec = 0;
value.it_interval.tv_nsec = 0;
timer_settime (gTimerid, 0, &value, NULL);
}
void timer_callback(int sig)
{
printf(" Catched timer signal: %d ... !!\n", sig);
}
int main(int ac, char **av)
{
(void) signal(SIGALRM, timer_callback);
start_timer();
while(1);
}
在Linux和其他POSIX系统上,timer_create
是您正在寻找的功能。将定时器设置为通过信号传送,它将非常可靠。不要使用旧的ualarm
或setitimer
apis,它们已被弃用并且有各种丑陋的问题你可能不想进入,除非你已经是实时unix东西的专家......
您有两个选项可以每隔一秒调用一个函数:
第一个选项肯定更准确,但CPU消耗更多,响应更少。它可以简单地用while
或for
循环完成。
这里有一个关于busy-wait循环如何的小例子:
#include <time.h>
#define TIME_TO_WAIT 1 /* wait for one second */
...
clock_t last = clock();
while(1) {
clock_t current = clock();
if (current >= (last + TIME_TO_WAIT * CLOCKS_PER_SEC)) {
yourSpecialFunction(); /* insert your function here */
last = current;
}
}
第二个选项可能不太准确(因为您的进程可能等待的时间少于或超过指定的时间),但它是多处理和调度方面的首选选项。您可以使用您的系统sleep()
/ usleep()
/ Sleep()
(取决于您的系统)功能。或者,您可以使用信号。
ualarm()
可能是最简单的方法。正如其他人所提到的,不能保证完美的准确性,但分辨率可能已足够。
void each_sec(int x)
{
printf("%d", (int)time(NULL));
}
int main()
{
signal(SIGALRM, each_sec);
ualarm(1000000, 1000000);
}
为了清晰起见,我使用了signal
,但sigaction
/ sigprocmask
更具便携性和特色。
在Unix / Linux上,你可以使用一个计时器,这是一个例子:
#include <stdio.h>
#include <signal.h>
#include <sys/time.h>
int limit = 10;
/* signal process */
void timeout_info(int signo)
{
if(limit == 0)
{
printf("Sorry, time limit reached.\n");
exit(0);
}
printf("only %d senconds left.\n", limit--);
}
/* init sigaction */
void init_sigaction(void)
{
struct sigaction act;
act.sa_handler = timeout_info;
act.sa_flags = 0;
sigemptyset(&act.sa_mask);
sigaction(SIGPROF, &act, NULL);
}
/* init */
void init_time(void)
{
struct itimerval val;
val.it_value.tv_sec = 1;
val.it_value.tv_usec = 0;
val.it_interval = val.it_value;
setitimer(ITIMER_PROF, &val, NULL);
}
int main(void)
{
char *str;
char c;
init_sigaction();
init_time();
printf("You have only 10 seconds for thinking.\n");
while(1);
exit(0);
}
用你自己的函数代替timeout_info
在Linux上,使用select()
进行计时是很常见的。这样,您还可以收到有关文件描述符活动的通知。
您需要为区间设置struct timeval
并将其作为select的最后一个参数传递。