需要说明在 GNU C 中使用 settimer 和 alarm 功能的程序
Posted
技术标签:
【中文标题】需要说明在 GNU C 中使用 settimer 和 alarm 功能的程序【英文标题】:need programs that illustrate use of settimer and alarm functions in GNU C 【发布时间】:2010-01-18 13:01:27 【问题描述】:谁能用一些程序示例来说明gnu C中settimer或alarm函数的使用?
我有一个持续处理一些数据的程序,我需要设置一个每隔 t 秒响一次的计时器/警报,作为响应,我需要将处理后的数据存储到一个文件中。该文件写入必须是异步的。我浏览了 GNU C 库页面,但我不能理解太多..
[编辑]
我得到了这个程序:
#include <stdio.h>
#include <signal.h>
#include <sys/time.h>
#define INTERVAL 1
int howmany = 0;
void alarm_wakeup (int i)
struct itimerval tout_val;
signal(SIGALRM,alarm_wakeup);
howmany += INTERVAL;
printf("\n%d sec up partner, Wakeup!!!\n",howmany);
tout_val.it_interval.tv_sec = 0;
tout_val.it_interval.tv_usec = 0;
tout_val.it_value.tv_sec = INTERVAL; /* 10 seconds timer */
tout_val.it_value.tv_usec = 0;
setitimer(ITIMER_REAL, &tout_val,0);
void exit_func (int i)
signal(SIGINT,exit_func);
printf("\nBye Bye!!!\n");
exit(0);
int main ()
struct itimerval tout_val;
tout_val.it_interval.tv_sec = 0;
tout_val.it_interval.tv_usec = 0;
tout_val.it_value.tv_sec = INTERVAL; /* 10 seconds timer */
tout_val.it_value.tv_usec = 0;
setitimer(ITIMER_REAL, &tout_val,0);
signal(SIGALRM,alarm_wakeup); /* set the Alarm signal capture */
signal(SIGINT,exit_func);
while (1)
//printf("!");
return 0;
但似乎我在计时器开启时无能为力.. 我应该修改什么以满足我的需要?请建议.. [/编辑]
【问题讨论】:
【参考方案1】:这是来自here 的示例,它使用setitimer()
定期调用DoStuff()
。
这里的关键是调用setitimer()
会导致操作系统调度SIGALRM
在指定时间过去后发送到您的进程,并且由您的程序在该信号到来时处理该信号。您可以通过为信号类型(在本例中为DoStufF()
)注册一个信号处理函数来处理信号,之后操作系统将知道在计时器到期时调用该函数。
您可以阅读setitimer()
man page 以了解参数是什么以及如何取消计时器。
注意:如果您希望计时器只触发一次,则必须调用alarm()
或ualarm()
而不是setitimer()
。
/*
* setitimer.c - simple use of the interval timer
*/
#include <sys/time.h> /* for setitimer */
#include <unistd.h> /* for pause */
#include <signal.h> /* for signal */
#define INTERVAL 500 /* number of milliseconds to go off */
/* function prototype */
void DoStuff(void);
int main(int argc, char *argv[])
struct itimerval it_val; /* for setting itimer */
/* Upon SIGALRM, call DoStuff().
* Set interval timer. We want frequency in ms,
* but the setitimer call needs seconds and useconds. */
if (signal(SIGALRM, (void (*)(int)) DoStuff) == SIG_ERR)
perror("Unable to catch SIGALRM");
exit(1);
it_val.it_value.tv_sec = INTERVAL/1000;
it_val.it_value.tv_usec = (INTERVAL*1000) % 1000000;
it_val.it_interval = it_val.it_value;
if (setitimer(ITIMER_REAL, &it_val, NULL) == -1)
perror("error calling setitimer()");
exit(1);
while (1)
pause();
/*
* DoStuff
*/
void DoStuff(void)
printf("Timer went off.\n");
【讨论】:
谢谢你,如果我想让整个警报作为后台运行,我该如何修改它,同时我可以处理一些数据.. 当警报响起时,我写一些东西到文件..正如我之前所说,这两个即处理和文件写入都是异步的.. 非常感谢,我对这个程序做了一些改动,我几乎得到了我想要的..(我现在要为我目前正在工作的数据包捕获项目尝试它) 在您的代码中,您最终会在 main() 中旋转,因此您可以在那里进行处理,而不是空循环。每当您获得 SIGALRM 时,您的代码将暂停,信号处理程序将获得控制权。信号处理程序完成后,您的代码将再次继续。因此,您可以使用信号处理程序设置一个标志,指示您应该写入文件,然后在处理循环中检查该标志。如果已设置,您将写入文件并将标志重置为 false。但是这个解决方案不是异步的,即警报/信号处理程序只会设置一个标志而不是写入文件。 (我上面的空间用完了)你在写文件的时候要小心,这样你正在写的数据结构处于一致的状态,而不是被主进程修改。这就是设置标志的方法很好的原因。以上是关于需要说明在 GNU C 中使用 settimer 和 alarm 功能的程序的主要内容,如果未能解决你的问题,请参考以下文章