我有这个C ++程序。它有一个简单的for循环,可以打印1到20之间的数字。在此之间,执行,计时器到期多次,每次到期时,它应该打印信号处理程序的输出。
不幸的是我没有得到这个输出。它只是简单地打印从1到20的数字。有人可以帮助我吗?
提前致谢
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <signal.h>
#include <time.h>
#define CLOCKID CLOCK_REALTIME
#define SIG 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;
}
}
但如果我设置“long long freq_nanosecs = 1”,那么输出只有一次来自定时器。应该重复
答案 0 :(得分:2)
0.011是双字面值,您将其指定为long,因此将其转换为0.这只是将freq_nanosecs设置为0.
long freq_nanosecs=0.011
由于定时器值为0,因此取消定时器。
timer_settime(timerid, 0, &its, NULL)
答案 1 :(得分:1)
首先要做的事情:请不要使用signal(2)
来安装信号处理程序。请改用sigaction(2)
; signal(2)
不可靠且非常难以移植。
接下来,您尝试在信号处理程序中使用printf(3)
。 printf(3)
不是信号安全功能。允许在信号处理程序中使用的唯一“标准”函数列在signal(7)
中。 (您也可以调用自己的函数, iff 它们只调用signal(7)
中列出的函数或执行非常简单的操作,例如设置一个标志来指示信号已经发生。)
答案 2 :(得分:0)
未安装信号处理程序。调用sigaction函数如下:
sa.sa_flags = SA_RESETHAND;
sa.sa_handler = handler;
sigaction(SIG, &sa, NULL);
sa_flags SA_RESETHAND(man sigaction)
调用信号处理程序后,将信号操作恢复为默认状态
和(男人7信号)
未处理的实时信号的默认操作是终止 接收过程。
打印前,接收下一个实时信号,然后退出程序。
请将sa_flags设置为零。