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.
精彩评论