欢迎您访问365答案网,请分享给你的朋友!
生活常识 学习资料

linux用户空间周期定时器C语言使用demo使用多线程实现定时器效率对比及一个问题记录

时间:2023-04-25

#include #include #include #include #include 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 %ldn", 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 #include #include #include #include #include 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 %ldn", 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 %ldn", 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");#elsepthread_t ptid;pthread_create(&ptid, NULL, producter, NULL);pthread_join(ptid, NULL);#endif for(;;)sleep(10); return 0;}

使用linux库定时器时的资源占用:

使用多线程时的资源占用:

 

一目了然! 

Copyright © 2016-2020 www.365daan.com All Rights Reserved. 365答案网 版权所有 备案号:

部分内容来自互联网,版权归原作者所有,如有冒犯请联系我们,我们将在三个工作时内妥善处理。