2014-03-03 27 views
-1
#include <signal.h> 
#include <unistd.h> 
#include <errno.h> 
#include <sys/types.h> 
#include <sys/socket.h> 
#include <netdb.h> 

#include <netinet/in.h> 
#include <arpa/inet.h> 
typedef unsigned int uint32; 





#define million 1000000L 

double duration2ms, duration10ms, duration100ms; 
double Task2ms_Raster, Task10ms_Raster, Task100ms_Raster; 
timer_t firstTimerID, secondTimerID, thirdTimerID; 





void TASK1(Task2ms_Raster) 
{ 

    struct timespec start, stop; 
    double StartTime, StopTime; 
    int a=1, b=3,c; 

     if((StartTime = clock_gettime(CLOCK_REALTIME, &start)) == -1) 
     { 
      perror("clock gettime"); 

     } 
     StartTime =start.tv_sec + 0.0000001 * start.tv_nsec; 
     printf("start time is %lf", StartTime); 


     printf("value is %d",c); 




     printf("ETAS1\n"); 
    if((StopTime = clock_gettime(CLOCK_REALTIME, &stop)) == -1) 
    { 
      perror("clock gettime"); 

     } 
    StopTime = stop.tv_sec + 0.0000001 * stop.tv_nsec; 
    printf("stop time is %lf", StopTime); 


    duration2ms = StopTime - StartTime; 
     printf("time difference is= %lf\n", duration2ms); 
} 

void TASK2(Task10ms_Raster) 
{ 
    int a,b,c; 
    struct timespec start, stop; 
    double StartTime, StopTime; 

      if(clock_gettime(CLOCK_REALTIME, &start) == -1) { 
       perror("clock gettime"); 

      } 
      StartTime =start.tv_sec + 0.0000001 * start.tv_nsec; 
       printf("start time is %lf", StartTime); 







       printf("ETAS2\n"); 
      if((StopTime = clock_gettime(CLOCK_REALTIME, &stop)) == -1) 
      { 
         perror("clock gettime"); 

        } 
      StopTime = stop.tv_sec + 0.0000001 * stop.tv_nsec; 
      printf("stop time is %lf", StopTime); 
    duration10ms = (stop.tv_sec - start.tv_sec) 
        + (double)(stop.tv_nsec - start.tv_nsec) 
        /(double)million; 
      printf("time difference is= %lf\n", duration10ms); 
} 


void TASK3(Task100ms_Raster) 
{ 
    int a,b,c; 
    struct timespec start, stop; 
    double StartTime, StopTime; 


      if(clock_gettime(CLOCK_REALTIME, &start) == -1) { 
       perror("clock gettime"); 

      } 

      StartTime =start.tv_sec + 0.0000001 * start.tv_nsec; 
       printf("start time is %lf", StartTime); 





       printf("value is %d",c); 




       printf("ETAS1\n"); 
      if((StopTime = clock_gettime(CLOCK_REALTIME, &stop)) == -1) 
      { 
         perror("clock gettime"); 

        } 
      StopTime = stop.tv_sec + 0.0000001 * stop.tv_nsec; 
      printf("stop time is %lf", StopTime); 

    duration100ms = StopTime -StartTime; 
      printf("time difference is= %lf\n", duration100ms); 
} 



static void timerHandler(int sig, siginfo_t *si, void *uc) 
{ 
    timer_t *tidp; 

    tidp = si->si_value.sival_ptr; 

    if (*tidp == firstTimerID) 

     TASK1(Task2ms_Raster); 
    else if (*tidp == secondTimerID) 
     TASK2(Task10ms_Raster); 
    else if (*tidp == thirdTimerID) 
     TASK3(Task100ms_Raster); 
} 


static int makeTimer(char *name, timer_t *timerID, int expireMS, int intervalMS) 
{ 
    struct sigevent   te; 
    struct itimerspec  its; 
    struct sigaction  sa; 
    int      sigNo = SIGRTMIN; 

    /* Set up signal handler. */ 
    sa.sa_flags = SA_SIGINFO; 
    sa.sa_sigaction = timerHandler; 
    sigemptyset(&sa.sa_mask); 
    if (sigaction(sigNo, &sa, NULL) == -1) 
    { 
     perror("sigaction"); 
    } 

    /* Set and enable alarm */ 
    te.sigev_notify = SIGEV_SIGNAL; 
    te.sigev_signo = sigNo; 
    te.sigev_value.sival_ptr = timerID; 
    timer_create(CLOCK_REALTIME, &te, timerID); 

    its.it_interval.tv_sec = 0; 
    its.it_interval.tv_nsec = intervalMS * 100000; 
    its.it_value.tv_sec = 0; 
    its.it_value.tv_nsec = expireMS * 100000; 
    timer_settime(*timerID, 0, &its, NULL); 

    return 1; 
} 


int main() 
{ 

        makeTimer("First Timer", &firstTimerID, 2, 2); //2ms 
        makeTimer("Second Timer", &secondTimerID, 10, 10); //10ms 
        makeTimer("Third Timer", &thirdTimerID, 100, 100); //100ms 

       while(1) 
        ;; 

} 

我创建了一个计时器,每2ms,10ms和100ms调用一次任务。我正在使用处理程序来处理任务。上面的代码不会中断task10的精确10ms,task3 100ms。它不会在正确的位置中断,输出如下所示。为什么这不是在正确的时间打断?

输出: 10ms的 2ms的 2ms的 10ms的 2ms的 10ms的 2ms的 2ms的 10ms的 2ms的 10ms的 100ms的 2ms的 10ms的 2ms的 10ms的 2ms的 10ms的 2ms的 10ms的 2ms的 10ms的 2ms 10ms的 2ms的 10ms的 100ms的 2ms的 10ms的 2ms的 10ms的 2ms的 10ms的 2ms的 10ms的 2ms的 10ms的 100ms的 2ms的 10ms的 2ms的 2ms的 10ms的 2ms的 2ms的 10ms的 2ms的 2ms的 10ms 2ms 10ms 2ms的 2ms的 10ms的 100ms的 2ms的 2ms的 10ms的 2ms的 10ms的 2ms的 2ms的 10ms的 2ms的 10ms的 2ms的 10ms的 2ms的 10ms的 2ms的 10ms的 100ms的 2ms的 10ms的 2ms的 10ms的 2ms 10ms 2ms 10ms 2ms 是什么原因?

+0

尝试将2,10和100更改为20,100和1000.我怀疑它会奇迹般地工作然后(调用信号处理程序加上'printf'可能需要比2ms更长的时间,并且您正在丢失信号 - - 信号未被排队!)。通常情况下,定时器分辨率应该足够好2ms,(无论如何它都在我的系统上!)。 – Damon

+0

你说的是真的!有时它会工作,有时不会。如何排队信号?有没有其他方法可以调用这个任务? – user3354789

+0

信号不排队(好吧,RT信号做到了一定的限度,但这没有帮助),对此没有什么可做的。除了更快地退出处理程序,没有其他办法。不用调用'printf',你可以原子地增加一个计数器(或者发布一个'eventfd'或一个信号量),然后根据这个值在处理器之外进行实际的打印。或者,如果可能的话,不要频繁地启动计时器。 – Damon

回答

0

struct itimerspec中的两个字段是秒和纳秒。毫秒中有1,000,000纳秒,而不是100,000。

因此,这是错误的:

its.it_interval.tv_nsec = intervalMS * 100000; 
its.it_value.tv_nsec = expireMS * 100000; 

您正在运行的结果(或试图运行)的定时器,快10倍,比你想象的。如果你在处理程序中所做的任何事情都无法跟上信号,那么他们只会排队等候一小段时间,然后他们就会被抛弃。在这一点上,处理什么信号和丢弃什么是不可预测的。

我不这样做,BTW,甚至看到这种行为,当我在两个定时器的时间间隔,这使我相信比你想象不管你真正处理程序做需要更长的时间非常不起眼5岁的机器上运行此。

+0

非常感谢您的答复。如果我想有一个2ms的间隔,那么应该是什么修改? – user3354789

+0

我将它修改为1000000!那么也是同样的问题。 – user3354789