在另一个处理程序中时,SIGALRM处理程序不会运行

时间:2019-03-03 19:32:52

标签: c signals alarm

所以我正在研究一个类的信号分配,我们的目标是捕获SIGINT信号并要求退出(如果用户输入Ctrl-C 5次)。如果用户在十秒钟之内没有回复退出提示,它会自动退出。

为此,我的实现是在不屏蔽SIGALRM的情况下为SIGINT设置处理程序,然后从SIGINT处理程序内部调用alarm(),但是从我得到的输出中,似乎SIGALRM处理程序直到运行SIGINT处理程序已完成运行。

#include <stdio.h>     /* standard I/O functions                         */
#include <stdlib.h>    /* exit                                           */
#include <unistd.h>    /* standard unix functions, like getpid()         */
#include <signal.h>    /* signal name macros, and the signal() prototype */

/* first, define the Ctrl-C counter, initialize it with zero. */
int ctrl_c_count = 0;
int got_response = 0;
#define CTRL_C_THRESHOLD  5 

/* the Ctrl-C signal handler */
void catch_int(int sig_num)
{
  /* increase count, and check if threshold was reached */
  ctrl_c_count++;
  if (ctrl_c_count >= CTRL_C_THRESHOLD) {
    char answer[30];

    got_response = 0;
    alarm(5);

    /* prompt the user to tell us if to really
     * exit or not */
    printf("\nReally exit? [Y/n]: ");
    fflush(stdout);

    fgets(answer, sizeof(answer), stdin);
    if (answer[0] == 'n' || answer[0] == 'N') {
      printf("\nContinuing\n");
      fflush(stdout);
      /* 
       * Reset Ctrl-C counter
       */
      ctrl_c_count = 0;
      got_response = 1;
    }
    else {
      printf("\nExiting...\n");
      fflush(stdout);
      exit(0);
    }
  }
}

/* the SIGALRM signal handler */
void catch_alrm(int sig_num)
{
  printf("\nGot to alarm handler\n");
  if (got_response == 0)
  {
    printf("User taking too long to respond. Exiting ...\n");
    exit(0);
  }
}

int main(int argc, char* argv[])
{
  struct sigaction sa;
  sigset_t mask_set;  /* used to set a signal masking set. */

  /* setup mask_set */
  sigfillset(&mask_set);

  sigdelset(&mask_set, SIGALRM);

  /* set signal handlers */
  // set up the signal handler for Ctrl-C (SIGINT)
  sa.sa_handler = catch_int;
  sigaction(SIGINT, &sa, NULL);

  // set up signal handler for alarm (SIGALRM)
  sa.sa_handler = catch_alrm;
  sigaction(SIGALRM, &sa, NULL);

  while(1)
  {
    pause(); 
  }

  return 0;
}

谁能告诉我为什么SIGALRM处理程序要在SIGINT处理程序完成后才能运行?我知道我可能不应该在信号处理程序中进行打印和填充,但是正如我所说的,这是针对一类的,我被告知只能这样做。

任何帮助,我们将不胜感激!

0 个答案:

没有答案