栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

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

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

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

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

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

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

 

一目了然! 

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/744457.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号