为什么这不会在正确的时间打断?

时间:2014-03-03 17:30:02

标签: c linux timer signals scheduling

#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调用一次任务。我正在使用处理程序来处理任务。上面的代码不会在10ms时中断task2,而在100ms时中断task3。它不会在正确的位置中断,输出如下所示。

输出: 10毫秒 2MS 2MS 10毫秒 2MS 10毫秒 2MS 2MS 10毫秒 2MS 10毫秒 100毫秒 2MS 10毫秒 2MS 10毫秒 2MS 10毫秒 2MS 10毫秒 2MS 10毫秒 2MS 10毫秒 2MS 10毫秒 100毫秒 2MS 10毫秒 2MS 10毫秒 2MS 10毫秒 2MS 10毫秒 2MS 10毫秒 100毫秒 2MS 10毫秒 2MS 2MS 10毫秒 2MS 2MS 10毫秒 2MS 2MS 10毫秒 2MS 10毫秒 2MS 2MS 10毫秒 100毫秒 2MS 2MS 10毫秒 2MS 10毫秒 2MS 2MS 10毫秒 2MS 10毫秒 2MS 10毫秒 2MS 10毫秒 2MS 10毫秒 100毫秒 2MS 10毫秒 2MS 10毫秒 2MS 10毫秒 2MS 10毫秒 2MS 是什么原因?

1 个答案:

答案 0 :(得分:0)

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

所以这是错误的:

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

因此,您的计时器运行(或试图运行)比您想象的快10倍。如果您在处理程序中执行的任何操作都无法跟上信号,那么它们只会排到一个小的限制,然后它们就会被丢弃。在那一点上,处理什么信号以及丢弃什么信号是不可预测的。

我不这样做,顺便说一下,即使我在一台非常不起眼的5岁机器上以任何一个计时器间隔运行它,也会看到这种行为,这让我相信你的真正的处理程序正在做的事情需要更长的时间比你想象的还要好。