linux的定时器对select和usleep与sleep的影响

       这次项目我的部分在2个月前就已经完成,但是同事在最近的使用中经常发现我的程序模块出问题。我在我的电路板上运行的好好的为什么到他那就崩溃呢?经过2天的持续检查发现居然是定时器导致的,因为我使用了大量的sleep、select。下面我来说下原理。

       首先我的同事使用的是setitimer()

        int setitimer(int which, const struct itimerval *value, struct itimerval *ovalue));
        setitimer()比alarm功能强大,支持3种类型的定时器:
        ITIMER_REAL :     以系统真实的时间来计算,它送出SIGALRM信号。
        ITIMER_VIRTUAL : -以该进程在用户态下花费的时间来计算,它送出SIGVTALRM信号。
        ITIMER_PROF :     以该进程在用户态下和内核态下所费的时间来计算,它送出SIGPROF信号

        下面我们举一个例子

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <time.h>
#include <sys/time.h>
int sec;
void sigroutine(int signo){
    switch (signo){
        case SIGALRM:
            printf("Catch a signal -- SIGALRM \n");
            signal(SIGALRM, sigroutine);
            break;
    }
    return;
}
int main()
{
    struct itimerval value; 
    signal(SIGALRM, sigroutine);
    value.it_value.tv_sec = 1;
    value.it_value.tv_usec = 0;
    value.it_interval.tv_sec = 1;
    value.it_interval.tv_usec = 0;
    setitimer(ITIMER_REAL, &value, NULL); 

    while(1);
}

         这个例子是每秒发送一个SIGALRM信号。

         但这和select与sleep、usleep有什么关系呢?

         关系大着呢,因为在linux系统中这三个都会被SIGALRM中断导致退出函数。

         

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <errno.h>
#include <unistd.h>
#include <signal.h>
#include <sys/time.h>
#include "Camera.h"
#include "QuecOpen4G.h"
#include "Tool.h"
#include "ql_oe.h"


int sec;
void sigroutine(int signo){
    switch (signo){
        case SIGALRM:
            printf("Catch a signal -- SIGALRM \n");
            signal(SIGALRM, sigroutine);
            break;
        case SIGVTALRM:
            printf("Catch a signal -- SIGVTALRM \n");
            signal(SIGVTALRM, sigroutine);
            break;
    }
    return;
}

int main()
{
	char i = 0;
	struct itimerval value, ovalue, value2;  

	signal(SIGALRM, sigroutine);
	signal(SIGVTALRM, sigroutine);
	value.it_value.tv_sec = 1;
	value.it_value.tv_usec = 0;
	value.it_interval.tv_sec = 1;
	value.it_interval.tv_usec = 0;
	setitimer(ITIMER_REAL, &value, &ovalue);            //1秒打印一次信号     

	Camera_Paramete_Init();
	Camera_Init_Internet_Ip("192.168.1.100", "255.255.255.0");    
	Camera_Init_Camera("192.168.1.64", 13851, 0, 10);
	Camera_Start_Camera_Communicate();
	Camera_Take_Picture(0, "1.jpg");
	i = Camera_Get_Camera_Order_By_Id(0);
	printf("%d\n", i);
	while(  i != READ_CAMERA_VERSION )
	{
		i = Camera_Get_Camera_Order_By_Id(0);
		printf("%d\n", i);
		sleep(2);                                        //2秒打印一次i
	}
	Tool_Move_File("/usrdata/1.jpg", "/usrdata/11.jpg");
	while(1);
	return 0;
}

      这段程序是2秒打印一次状态,1秒打印一次信号。实际真的这样吗?

  完全不是,变成了1s打印一次状态,1s打印一次信号。

  所以最后我同事开了一个线程用usleep去模拟一个定时器。是我考虑不周到,坑了同事。

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值