参考这篇文章 https://blog.csdn.net/lixianlin/article/details/25604779
我看完这篇文章,一开始写下的测试代码是这样的#include <stdio.h>
#include <signal.h>
#include <sys/time.h>
// 回调函数
void handler(int sig)
{
static int count;
printf("handler: %d\n", count++);
}
int main(void)
{
// 注册回调函数
// 当程序收到SIGALRM信号后
// 暂停当前程序的执行,转去执行handler函数
// handler函数返回后再从暂停的位置继续向下执行
signal(SIGALRM, handler);
struct itimerval new_value;
new_value.it_interval.tv_sec = 0;
new_value.it_interval.tv_usec = 500000;
new_value.it_value.tv_sec = 0;
new_value.it_value.tv_usec = 0;
// 设置定时器
// 当定时器超时后让系统发送一个信号给当前程序
// ITIMER_REAL参数指明要让系统发送SIGALRM信号
setitimer(ITIMER_REAL, &new_value, NULL);
while(1)
;
return 0;
}
首先系统会在一个单位时间后对it_value递减,单位时间是多少,取决于你的系统,可能是10毫秒也可能是1毫秒,甚至是微妙、纳秒
总之就是系统会对it_value减一个合适的值,并不一定是减1,减多少取决于系统
系统每一个单位时间都对it_value减一个合适的值,直到it_value小于等于0
然后系统会做两件事
1.把it_interval复制到it_value,开始新一轮定时
2.发送一个信号,我们通过参数ITIMER_REAL要求发送SIGALRM
new_value.it_interval.tv_sec = 0;
new_value.it_interval.tv_usec = 500000;
new_value.it_value.tv_sec = 0;
new_value.it_value.tv_usec = 0;
我期望的是500毫秒发一个信号
调用完setitimer函数后立刻发一个信号,因为it_value为0
但是系统不允许我这样做,系统会把一开始的it_value为0作为定时器停止的标志
那么修改代码#include <stdio.h>
#include <signal.h>
#include <sys/time.h>
void handler(int sig)
{
static int count;
printf("handler: %d\n", count++);
}
int main(void)
{
signal(SIGALRM, handler);
struct itimerval new_value;
new_value.it_interval.tv_sec = 0;
new_value.it_interval.tv_usec = 500000;
new_value.it_value = new_value.it_interval;
setitimer(ITIMER_REAL, &new_value, NULL);
while(1)
;
return 0;
}
让it_value直接等于it_interval,也就是不要一开始就发信号了
这样确实可以了,500ms发一次信号
不知道你是不是对 tv_sec 和 tv_usec 的设置有疑问
我是应该只设置tv_sec还是只设置tv_usec ?
这两个是怎么表示时间的?
https://blog.csdn.net/lyc_daniel/article/details/11733715
“tv_sec为Epoch到创建struct timeval时的秒数,tv_usec为微秒数,即秒后面的零头”
看到 “秒后面的零头”,我明白了
这两个参数是一起表示时间的,就像是整数和小数分开存储一样
tv_sec存储秒,tv_usec存储微秒
那我又有了另一个问题,我能不能把tv_sec设置为0,通过设置tv_usec来定时任意时间?#include <stdio.h>
#include <signal.h>
#include <sys/time.h>
void handler(int sig)
{
static int count;
printf("handler: %d\n", count++);
}
int main(void)
{
signal(SIGALRM, handler);
struct itimerval new_value;
new_value.it_interval.tv_sec = 0;
new_value.it_interval.tv_usec = 1000000; // 1秒,6个0
new_value.it_value = new_value.it_interval;
setitimer(ITIMER_REAL, &new_value, NULL);
while(1)
;
return 0;
}
通过测试是
不能这样,tv_sec 表示秒的部分
tv_usec只能表示微秒和毫秒,会忽略超过毫秒的部分
#include <stdio.h>
#include <signal.h>
#include <sys/time.h>
void handler(int sig)
{
static int count;
printf("handler: %d\n", count++);
}
int main(void)
{
signal(SIGALRM, handler);
struct itimerval new_value;
new_value.it_interval.tv_sec = 0;
new_value.it_interval.tv_usec = 100000; // 100毫秒,5个0
new_value.it_value = new_value.it_interval;
setitimer(ITIMER_REAL, &new_value, NULL);
while(1)
;
return 0;
}
这样是可以的 |