Wenn Sie Strg + C drücken sendet das Betriebssystem ein Signal an den Prozess. Es gibt viele Signale und eines davon ist SIGINT. Das SIGINT ("Programmunterbrechung") ist eines der Beendigungssignale.
Es gibt noch ein paar weitere Arten von Beendigungssignalen, aber das Interessante an SIGINT ist, dass es von Ihrem Programm gehandhabt (abgefangen) werden kann. Die Standardaktion von SIGINT ist die Programmbeendigung. Das heißt, wenn Ihr Programm dieses Signal nicht speziell behandelt, wenn Sie Strg + C drücken Ihr Programm wird standardmäßig beendet.
Um die Standardaktion eines Signals zu ändern, müssen Sie das zu fangende Signal registrieren. Um ein Signal in einem C-Programm (zumindest unter POSIX-Systemen) zu registrieren, gibt es zwei Funktionen
- signal(int signum, sighandler_t handler);
- sigaction(int signum, const struct sigaction *act,struct sigaction *oldact);.
Diese Funktionen erfordern die Aufnahme des Headers signal.h in Ihren C-Code. Ich habe ein einfaches Beispiel für signal
bereitgestellt Funktion unten mit Kommentaren.
#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;
}
Hinweis:Sie sollten nur sichere/autorisierte Funktionen im Signalhandler aufrufen. Vermeiden Sie zum Beispiel den Aufruf von printf im Signalhandler.
Sie können diesen Code mit gcc kompilieren und von der Shell ausführen. Der Code enthält eine Endlosschleife, die ausgeführt wird, bis Sie SIGINT
senden Signal durch Drücken von Strg + C .
Sie können das Signalmakro verwenden.
Hier ist ein Beispiel, wie man damit umgeht:
#include <signal.h>
#include <stdio.h>
void sigint(int a)
{
printf("^C caught\n");
}
int main()
{
signal(SIGINT, sigint);
for (;;) {}
}
Beispielausgabe:
Ethans-MacBook-Pro:~ phyrrus9$ ./a.out
^C^C caught
^C^C caught
^C^C caught
^C^C caught
^C^C caught
Geben Sie Strg ein C bewirkt normalerweise, dass die Shell SIGINT
sendet zu deinem Programm. Fügen Sie einen Handler für dieses Signal hinzu (über signal(2)
oder sigaction(2)
), und Sie können mit Strg tun, was Sie wollen C gedrückt wird.
Alternativ, wenn Sie sich nur um die Bereinigung kümmern, bevor Ihr Programm beendet wird, richten Sie einen Exit-Handler über atexit(3)
ein vielleicht besser geeignet.