web-dev-qa-db-fra.com

Gestion des événements d'interruption Ctrl + C sous Linux

Je développe une application qui utilise C++ et se compile en utilisant Linux GNU C Compiler. Cependant, je veux invoquer une fonction lorsque l'utilisateur interrompt le script en utilisant CtrlC clés. Que devrais-je faire? Toutes les réponses seraient très appréciées.

25
mozcelikors

Lorsque vous appuyez sur Ctr + C, le système d'exploitation envoie un signal au processus. Il existe de nombreux signaux et l'un d'eux est SIGINT. Le SIGINT ("interruption de programme") est l'un des signaux de terminaison.

Il existe quelques autres types de signaux de terminaison, mais ce qui est intéressant avec SIGINT, c'est qu'il peut être géré (intercepté) par votre programme. L'action par défaut de SIGINT est l'arrêt du programme. Autrement dit, si votre programme ne gère pas spécifiquement ce signal, lorsque vous appuyez sur Ctr + C votre programme se termine comme action par défaut.

Pour modifier l'action par défaut d'un signal, vous devez enregistrer le signal à capturer. Pour enregistrer un signal dans un programme C (au moins sous les systèmes POSIX), il y a deux fonctions

  1. signal (int signum, sighandler_t handler);
  2. sigaction (int signum, const struct sigaction * act, struct sigaction * oldact); .

Ces fonctions nécessitent que l'en-tête signal.h soit inclus dans votre code C. J'ai fourni un exemple simple de la fonction signal ci-dessous avec des commentaires.

#include <stdio.h>
#include <stdlib.h>
#include <signal.h> //  our new library 
volatile sig_atomic_t flag = 0;
void my_function(int sig){ // can be called asynchronously
  flag = 1; // set flag
}

int main(){
  // Register signals 
  signal(SIGINT, my_function); 
  //      ^          ^
  //  Which-Signal   |-- which user defined function registered
  while(1)  
    if(flag){ // my action when signal set it 1
        printf("\n Signal caught!\n");
        printf("\n default action it not termination!\n");
        flag = 0;
    }     
  return 0;
}  

Remarque: vous ne devez appeler que fonctions sûres/autorisées dans le gestionnaire de signaux. Par exemple évitez d'appeler printf dans le gestionnaire de signal .

Vous pouvez compiler ce code avec gcc et l'exécuter à partir du shell. Il y a une boucle infinie dans le code et il fonctionnera jusqu'à ce que vous envoyiez un signal SIGINT en appuyant sur Ctr + C.

55
Grijesh Chauhan

Dactylographie CtrlC normalement, le shell envoie SIGINT à votre programme. Ajoutez un gestionnaire pour ce signal (via signal(2) ou sigaction(2) ), et vous pouvez faire ce que vous voulez quand CtrlC est pressé.

Alternativement, si vous ne vous souciez que de nettoyer avant la fin de votre programme, la configuration d'un gestionnaire de sortie via atexit(3) pourrait être plus appropriée.

11
Carl Norum

Vous pouvez utiliser la macro de signal.

Voici un exemple de la façon de le gérer:

#include <signal.h>
#include <stdio.h>
void sigint(int a)
{
    printf("^C caught\n");
}
int main()
{
    signal(SIGINT, sigint);
    for (;;) {}
}

Exemple de sortie:

Ethans-MacBook-Pro:~ phyrrus9$ ./a.out
^C^C caught
^C^C caught
^C^C caught
^C^C caught
^C^C caught
4
phyrrus9