开发者

C++ (under Linux) program not giving expected output ( timer )

I have this C++ program. It has a simple for loop which prints numbers from 1 to 20. Between this, execution, the timer expires multiple times, and each time it expires, it should print an output from signal handler.

Unfortunately i am not getting this output. And it is just simply printing the numbers from 1 to 20. Can someone please help me?

Thanks in advance

#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <signal.h>
#include <time.h>
#define CLOCKID CLOCK_REALTIME
#define SIG开发者_Go百科 SIGRTMIN
#define errExit(msg) do { perror(msg); exit(EXIT_FAILURE); \
} while (0)
#include <iostream>

using namespace std;

static int flag=0;
class timer{

static void
handler(int sig) {
  printf("Caught signal %d\n", sig);
  ::flag=1;
  signal(sig, handler);
}

public:

void timer_func()
{
timer_t timerid;
struct sigevent sev;
struct itimerspec its;
long long freq_nanosecs=1; // The timer frequency in nanosecs
sigset_t mask;
struct sigaction sa;

/* Establish handler for timer signal */

printf("Establishing handler for signal %d\n", SIG);

sa.sa_flags = SA_RESETHAND;
sa.sa_handler = handler;


 /* Create the timer */

 sev.sigev_notify = SIGEV_SIGNAL;
 sev.sigev_signo = SIG;
 sev.sigev_value.sival_ptr = &timerid;

 if (timer_create(CLOCKID, &sev, &timerid) == -1)
   errExit("timer_create");

 printf("timer ID is 0x%lx\n", (long) timerid);

 /* Start the timer */

 its.it_value.tv_sec = freq_nanosecs / 1000000000;
 its.it_value.tv_nsec = freq_nanosecs % 1000000000;
 its.it_interval.tv_sec = its.it_value.tv_sec;
 its.it_interval.tv_nsec = its.it_value.tv_nsec;

 if (timer_settime(timerid, 0, &its, NULL) == -1)
   errExit("timer_settime");
  }
 };

 int main() {

   timer ob;
   ob.timer_func();

   for(int i=0; i<20; i++) {
     sleep(1);
   if(flag) {
     cout << "Timer called" << endl;
     flag=0;
    }
   cout << "Printing i: " << i << endl;
  }
 } 

But if i set "long long freq_nanosecs = 1" in that also the output is only once from the timer. It should be repeated


0.011 is a double literal, you assign it to a long, so it's converted to 0. This simply sets freq_nanosecs to 0.

long freq_nanosecs=0.011

This disarms the timer since the timer values are 0.

timer_settime(timerid, 0, &its, NULL)


First things first: please do not use signal(2) to install signal handlers. Use sigaction(2) instead; signal(2) is unreliable and very unportable.

Next, you're trying to use printf(3) inside a signal handler. printf(3) is not a signal-safe function. The only "standard" functions you are allowed to use inside a signal handler are listed in signal(7). (You can also call your own functions, iff they only call functions listed in signal(7) or do very simple operations, such as setting a flag to indicate that a signal has occured.)


The signal handler is not installed. Call sigaction function as follows:

sa.sa_flags = SA_RESETHAND; 
sa.sa_handler = handler;
sigaction(SIG, &sa, NULL);

The sa_flags SA_RESETHAND (man sigaction)

Restore the signal action to the default state once the signal handler has been called

And (man 7 signal)

The default action for an unhandled real-time signal is to terminate the receiving process.

Before print, next real-time signal received, and exit the program.

Please set the sa_flags to zero.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜