Обработчик SIGALRM не запускается, когда внутри другого обработчика - PullRequest
0 голосов
/ 03 марта 2019

Итак, я работаю над заданием для сигналов для класса, и наша цель - поймать сигнал SIGINT и попросить выйти, если пользователь введет Ctrl-C 5 раз.Если пользователь не отвечает на запрос на выход в течение десяти секунд, он должен автоматически завершиться.

Моя реализация для этого - установить обработчик для SIGINT без маскировки SIGALRM, а затем вызвать alarm() изнутри SIGINT.обработчик, но из вывода, который я получаю, кажется, что обработчик 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 не завершится?Я знаю, что, вероятно, не следует печатать и что-то изнутри обработчика сигналов, но, как я уже сказал, это для класса, и мне сказали делать это только так.

Любая помощь приветствуется!

...