c - 为什么这没有在正确的时间中断?

标签 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)
                    ;;

}

我创建了一个计时器,每 2 毫秒、10 毫秒和 100 毫秒调用一次任务。我正在使用处理程序来处理任务。上面的代码并没有在正好 10ms 处中断任务 2,也没有在 100 毫秒处中断任务 3。它没有在正确的位置中断,输出如下所示。

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

最佳答案

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

所以这是错误的:

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

因此,您运行(或尝试运行)计时器的速度比您想象的快 10 倍。如果您在处理程序中所做的任何事情都无法跟上信号,那么它们只会排队到一个很小的限制,然后就会被丢弃。那时哪些信号被处理以及哪些信号被丢弃是不可预测的。

顺便说一句,即使我在一台非常不起眼的 5 年旧机器上以任一计时器间隔运行它,我也看不到这种行为,这让我相信无论您的真实处理程序正在做什么都需要更长的时间比你想象的要多。

关于c - 为什么这没有在正确的时间中断?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22153314/

相关文章:

c - 如何保留来自 Access 数据库的准确数字

使用套接字的 PHP 多播服务器

c - 函数 ‘mknod’ 的隐式声明,但我包含了 header

c# - ThreadAbortException 是否仍然强制执行 finally (try/catch) 部分中的代码?

java - 系统无法处理以纳秒为单位触发的事件,为什么?

c++ timer ,相当于 .NET System.Threading.Timer

c - "Generic C"是什么?

c - Sscanf 没有以相同的方式读取相同的行

java - 使用 JNI 将指向 double 组的 C 指针传递给 Java

linux - 关于在线程中阻塞 I/O 的问题