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 
#include 
#include 
#include 
#include 
#include 
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 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#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秒打印一次信号。实际真的这样吗?

linux的定时器对select和usleep与sleep的影响_第1张图片

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

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

你可能感兴趣的:(Linux)