C++;(在Linux下)程序未给出预期输出(计时器) 我有这个C++程序。它有一个简单的for循环,可以打印从1到20的数字。在执行期间,计时器会多次过期,每次过期时,它都会打印信号处理程序的输出

C++;(在Linux下)程序未给出预期输出(计时器) 我有这个C++程序。它有一个简单的for循环,可以打印从1到20的数字。在执行期间,计时器会多次过期,每次过期时,它都会打印信号处理程序的输出,c++,linux,timer,C++,Linux,Timer,不幸的是,我没有得到这个输出。它只是简单地打印从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 { p

不幸的是,我没有得到这个输出。它只是简单地打印从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;
  }
 } 
#包括
#包括
#包括
#包括
#包括
#定义CLOCKID CLOCK\u REALTIME
#定义SIG SIGRTMIN
#定义errExit(msg)do{perror(msg);exit(exit_FAILURE)\
}而(0)
#包括
使用名称空间std;
静态int标志=0;
班级计时器{
静态空隙
处理程序(int sig){
printf(“捕获的信号%d\n”,sig);
::flag=1;
信号(信号发生器,处理器);
}
公众:
无效计时器_func()
{
计时器\u t timerid;
结构sigfevent sev;
结构itimerspec its;
long long freq_nanoECS=1;//计时器频率(以nanoECS为单位)
sigset_t掩模;
struct-sigaction-sa;
/*建立定时器信号处理程序*/
printf(“为信号%d\n建立处理程序”,SIG);
sa.sa_flags=sa_RESETHAND;
sa.sa_handler=handler;
/*创建计时器*/
sev.sigev_notify=sigev_信号;
sev.sigev_signo=SIG;
sev.sigev_value.sival_ptr=&timerid;
如果(计时器\u创建(时钟ID、&sev、&timerid)=-1)
errExit(“计时器创建”);
printf(“计时器ID为0x%lx\n”,(长)timerid);
/*启动计时器*/
its.it_value.tv_sec=freq_nanosecs/100000000;
its.it_value.tv_nsec=freq_nanosecs%100000000;
its.it_interval.tv_sec=its.it_value.tv_sec;
its.it\u interval.tv\u nsec=its.it\u value.tv\u nsec;
if(timer_settime(timerid,0,&its,NULL)=-1)
errExit(“计时器设置时间”);
}
};
int main(){
定时器ob;
ob.timer_func();

对于(inti=0;i0.011)是一个双字面值,您将其分配给long,因此它被转换为0。这只是将freq_nanosecs设置为0

long freq_nanosecs=0.011
这将解除计时器的警报,因为计时器值为0

timer_settime(timerid, 0, &its, NULL)

第一件事:请不要使用
signal(2)
安装信号处理程序。使用
sigaction(2)
代替;
signal(2)
不可靠且非常不可移植


接下来,您尝试在信号处理程序中使用
printf(3)
printf(3)
不是信号安全函数。中列出了信号处理程序中允许使用的唯一“标准”函数。(您也可以调用自己的函数,如果它们只调用
signal(7)中列出的函数)
或执行非常简单的操作,例如设置标志以指示信号已发生。)

未安装信号处理程序。按如下方式调用sigaction函数:

sa.sa_flags = SA_RESETHAND; 
sa.sa_handler = handler;
sigaction(SIG, &sa, NULL);
sa_标记sa_RESETHAND(手动)

调用信号处理程序后,将信号操作恢复为默认状态

及(man 7信号)

未处理的实时信号的默认操作是终止 接收过程

打印前,收到下一个实时信号,并退出程序


请将sa_标志设置为零。

谢谢您的回复。但是如果我设置“long long freq_nanosecs=1”在这种情况下,计时器的输出也只有一次。它应该重复。@kingsmasher,我认为你不应该期望实际睡眠时间为十亿分之一秒。10毫秒更合理;试试
freq\u nanosecs=1000000
或足够长的时间睡眠的东西。谢谢,但为什么输出不符合eexpectation?在main()中,我的代码处于休眠状态,在此期间,我希望计时器会多次超时,每次都会打印它。