timer_gettime不能与多个计时器一起使用

时间:2015-03-16 18:33:14

标签: c timer

问题是我正在尝试运行可以同时触发不同计时器的代码。也就是说,当用户键入3时,触发第一个。如果在到期之前引入另一个3,则将启动第二个计时器,并且将显示两个触发器之间的差异。在这种情况下,timer_gettime只能运行一次。我尝试了所有我能想象的东西,但是,it_value_tv_sec和_nsec在第一次到期后返回零。

以下是我正在测试的代码:

提前谢谢!

#include <stdio.h>
#include <signal.h>
#include <time.h>


timer_t firstTimerID;
timer_t secondTimerID;
timer_t thirdTimerID;
timer_t fourthTimerID;
int z=0;
int a=0;
int t_block3=4;
float delay_blocks;

struct itimerspec it;
struct itimerspec its;

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

    tidp = si->si_value.sival_ptr;

    if ( *tidp == firstTimerID ){
        printf("First timer\n");
    }
    else if ( *tidp == secondTimerID ){
        printf("Second timer\n");
    }
    else if ( *tidp == thirdTimerID ){
        printf("Third timer\n");
    }
    else if ( *tidp == fourthTimerID ){
        printf("Fourth timer\n");
    }

    z--;
    printf("%d", z);

}

static int makeTimer( timer_t *timerID, int time)
{
    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; //Action when singal is triggered
    sigemptyset(&sa.sa_mask);
    if (sigaction(sigNo, &sa, NULL) == -1) {
        perror("sigaction");
    }

    // Set and enable alarm 
    te.sigev_notify = SIGEV_SIGNAL; //Gnerate alarm upon expiration
    te.sigev_signo = sigNo; //SIGALRM
    te.sigev_value.sival_ptr = timerID; //Timer ID
    //Create a per_process timer using the timer ID
    timer_create(CLOCK_REALTIME, &te, timerID);

    //Interval for starting again 
    its.it_interval.tv_sec = 0 ;
    its.it_interval.tv_nsec = 0;
    //Timer time
    its.it_value.tv_sec = time;
    its.it_value.tv_nsec = 0;
    //Arm/disarmer a per process time
    timer_settime(*timerID, 0, &its, NULL);

    return 1;
}

int main(){

while (1){
    printf("Enter the number of the block\n");
    if (scanf(" %d", &a) == 1){

    switch(a){
    case 3: printf("Block number three, belt will proceed to stop in 12 seconds\n");
            if (z==0){                  
            makeTimer(&firstTimerID, t_block3);
            }else if (z==1){
                makeTimer(&secondTimerID, 4);
                timer_gettime(&firstTimerID,&it);
                delay_blocks=t_block3-(it.it_value.tv_sec+(it.it_value.tv_nsec*0.000000001));
                printf("Difference between the first and the second timer = %f\n", delay_blocks);

            }else if (z==2){
            makeTimer(&thirdTimerID, 4);
            }else if (z==3){
            makeTimer(&fourthTimerID, 4);
            }
            z++;
            break;

    case 2: printf("Block number two, belt will proceed to stop in 10 seconds\n");
                    //sleep(1);
                    break;

    case 4: printf("Block number four, belt won't stop\n");
                    //sleep(1);
                    break;
    default:printf("Wrong lecture\n");

    }
    }

}

}

一旦收到第一个信号,我也尝试使用timer_delete,但在这种情况下,总是调用gettime,它会返回相同的值,无论是同一时间还是第三个。

2 个答案:

答案 0 :(得分:0)

看起来您的问题是您每次都在重新创建计时器。 仅调用timer_create一次并重用相同的计时器 我在下面有一个工作示例。

#include <stdio.h>
#include <signal.h>
#include <time.h>


timer_t firstTimerID;
timer_t secondTimerID;
timer_t thirdTimerID;
timer_t fourthTimerID;
int z = 0;
int a = 0;
int t_block3 = 4;
float delay_blocks;


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

  tidp = si->si_value.sival_ptr;

  if (*tidp == firstTimerID) {
    printf ("First timer\n");
  } else if (*tidp == secondTimerID) {
    printf ("Second timer\n");
  } else if (*tidp == thirdTimerID) {
    printf ("Third timer\n");
  } else if (*tidp == fourthTimerID) {
    printf ("Fourth timer\n");
  }

  z--;
  printf ("%d\n", z);

}

static int makeTimer (timer_t * timerID) {
  struct sigevent te;
  struct sigaction sa;
  int sigNo = SIGRTMIN;

  // Set up signal handler.
  sa.sa_flags = SA_SIGINFO;
  sa.sa_sigaction = timerHandler;       //Action when singal is triggered
  sigemptyset (&sa.sa_mask);
  if (sigaction (sigNo, &sa, NULL) == -1) {
    perror ("sigaction");
  }
  // Set and enable alarm
  te.sigev_notify = SIGEV_SIGNAL;       //Gnerate alarm upon expiration
  te.sigev_signo = sigNo;       //SIGALRM
  te.sigev_value.sival_ptr = timerID;   //Timer ID
  //Create a per_process timer using the timer ID
  timer_create (CLOCK_REALTIME, &te, timerID);

}

static int setTimer(timer_t * timerID, int time) {
  struct itimerspec its;
  //Interval for starting again
  its.it_interval.tv_sec = 0;
  its.it_interval.tv_nsec = 0;
  //Timer time
  its.it_value.tv_sec = time;
  its.it_value.tv_nsec = 0;
  //Arm/disarmer a per process time
  timer_settime (*timerID, 0, &its, NULL);

  return 1;
}

int main () {
  struct itimerspec it;
  makeTimer(&firstTimerID);
  makeTimer(&secondTimerID);
  makeTimer(&thirdTimerID);
  makeTimer(&fourthTimerID);

  while (1) {
    printf ("Enter the number of the block\n");
    if (scanf (" %d", &a) == 1) {

      switch (a) {
      case 3:
        printf
          ("Block number three, belt will proceed to stop in 12 seconds\n");
        if (z == 0) {
          setTimer (&firstTimerID, t_block3);
        } else if (z == 1) {
          setTimer (&secondTimerID, 4);
          timer_gettime (&firstTimerID, &it);
          delay_blocks =
            t_block3 - (it.it_value.tv_sec +
                        (it.it_value.tv_nsec * 0.000000001));
          printf ("Difference between the first and the second timer = %f\n",
                  delay_blocks);

        } else if (z == 2) {
          setTimer (&thirdTimerID, 4);
        } else if (z == 3) {
          setTimer (&fourthTimerID, 4);
        }
        z++;
        break;

      case 2:
        printf
          ("Block number two, belt will proceed to stop in 10 seconds\n");
        //sleep(1);
        break;

      case 4:
        printf ("Block number four, belt won't stop\n");
        //sleep(1);
        break;
      default:
        printf ("Wrong lecture\n");

      }
    }

  }

} 

答案 1 :(得分:0)

当你将it_interval.tv_sec + it_interval.tv_nec设置为零时,你就有了一次性计时器。

如此处所述http://man7.org/linux/man-pages/man2/timer_settime.2.html

问候