#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <sys/time.h>
void signalHandler(int signo)
{
static int i = 0;
static struct timeval tvNew ={0,0};
static struct timeval tvOld ={0,0};
switch (signo){
case SIGALRM:
if(tvOld.tv_sec != 0)
{
gettimeofday(&tvNew,NULL);
printf("i is %d time is %ld\n", i%25, (tvNew.tv_sec - tvOld.tv_sec)*1000*1000 + tvNew.tv_usec - tvOld.tv_usec);
tvOld = tvNew;
}
else
{
gettimeofday(&tvOld,NULL);
}
usleep((i %25) * 100000);
//if(i % 2 == 0)
// sleep(2);
i++;
break;
}
}
int main(int argc, char *argv[])
{
signal(SIGALRM, signalHandler);
struct itimerval new_value, old_value;
new_value.it_value.tv_sec = 1;//执行完setitimer后过多少秒进入第一个SIGALRM信号处理
new_value.it_value.tv_usec = 0;//执行完setitimer后过多少微秒进入SIGALRM第一个信号处理,第一个参数的小数,本例中表示1s后进入第一个SIGALRM信号处理
new_value.it_interval.tv_sec = 1;//开始执行第一个SIGALRM信号处理后周期进入SIGALRM信号处理的周期秒
new_value.it_interval.tv_usec = 0;//开始执行第一个SIGALRM信号处理后周期进入SIGALRM信号处理的周期微秒,本demo表示定时周期为1s
setitimer(ITIMER_REAL, &new_value, &old_value);
//system("date");
for(;;);
return 0;
}
典型demo如上,执行结果如下:
i is 1 time is 999992 i is 2 time is 1000003 i is 3 time is 1000000 i is 4 time is 1000011 i is 5 time is 999982 i is 6 time is 1000000 i is 7 time is 1000001 i is 8 time is 1000002 i is 9 time is 999997 i is 10 time is 999997 i is 11 time is 1000071 i is 12 time is 1100136 i is 13 time is 1200107 i is 14 time is 1300159 i is 15 time is 1400149 i is 16 time is 1500147 i is 17 time is 1600191 i is 18 time is 1700155 i is 19 time is 1800142 i is 20 time is 1900158 i is 21 time is 2000131 i is 22 time is 2100134 i is 23 time is 2200131 i is 24 time is 2300165 i is 0 time is 2400144 i is 1 time is 497905 i is 2 time is 999983 i is 3 time is 999996 i is 4 time is 1000002 i is 5 time is 999998 i is 6 time is 999999 i is 7 time is 1000004 i is 8 time is 1000005 i is 9 time is 999989 i is 10 time is 999997 i is 11 time is 1000078 i is 12 time is 1100179 ........
有一个问题就是为啥存在i is 1 time is 497905 这个打印,而不是间隔一秒左右?记录下,以后撸下系统源码看看,如果各位有高见也可解答下
接下来看下linux定时器与多线程实现定时器的效率对比,测试代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <sys/time.h>
#include <pthread.h>
void signalHandler(int signo)
{
static int i = 0;
static struct timeval tvNew ={0,0};
static struct timeval tvOld ={0,0};
switch (signo){
case SIGALRM:
if(tvOld.tv_sec != 0)
{
gettimeofday(&tvNew,NULL);
printf("i is %d time is %ld\n", i%25, (tvNew.tv_sec - tvOld.tv_sec)*1000*1000 + tvNew.tv_usec - tvOld.tv_usec);
tvOld = tvNew;
}
else
{
gettimeofday(&tvOld,NULL);
}
//usleep((i %25) * 100000);
//if(i % 2 == 0)
// sleep(2);
i++;
break;
}
}
void *producter(void *arg)
{
static int i = 0;
static struct timeval tvNew ={0,0};
static struct timeval tvOld ={0,0};
while(1)
{
if(tvOld.tv_sec != 0)
{
gettimeofday(&tvNew,NULL);
printf("i is %d time is %ld\n", i%25, (tvNew.tv_sec - tvOld.tv_sec)*1000*1000 + tvNew.tv_usec - tvOld.tv_usec);
tvOld = tvNew;
}
else
{
gettimeofday(&tvOld,NULL);
}
sleep(1);
}
}
int main(int argc, char *argv[])
{
#if 1
signal(SIGALRM, signalHandler);
struct itimerval new_value, old_value;
new_value.it_value.tv_sec = 1;//执行完setitimer后过多少秒进入第一个SIGALRM信号处理
new_value.it_value.tv_usec = 0;//执行完setitimer后过多少微秒进入SIGALRM第一个信号处理,第一个参数的小数,本例中表示1s后进入第一个SIGALRM信号处理
new_value.it_interval.tv_sec = 1;//开始执行第一个SIGALRM信号处理后周期进入SIGALRM信号处理的周期秒
new_value.it_interval.tv_usec = 0;//开始执行第一个SIGALRM信号处理后周期进入SIGALRM信号处理的周期微秒,本demo表示定时周期为1s
setitimer(ITIMER_REAL, &new_value, &old_value);
//system("date");
#else
pthread_t ptid;
pthread_create(&ptid, NULL, producter, NULL);
pthread_join(ptid, NULL);
#endif
for(;;)
sleep(10);
return 0;
}
使用linux库定时器时的资源占用:
使用多线程时的资源占用:
?
一目了然!?
|