Když stisknete Ctr + C , operační systém vyšle signál procesu. Existuje mnoho signálů a jedním z nich je SIGINT. SIGINT ("přerušení programu") je jedním z ukončovacích signálů.
Existuje několik dalších druhů signálů ukončení, ale zajímavá věc na SIGINT je, že je může zpracovat (zachytit) váš program. Výchozí akcí SIGINT je ukončení programu. To znamená, že pokud váš program konkrétně nezpracovává tento signál, když stisknete Ctr + C váš program se ukončí jako výchozí akce.
Chcete-li změnit výchozí akci signálu, musíte zaregistrovat signál, který má být zachycen. Pro registraci signálu v programu C (alespoň v systémech POSIX) existují dvě funkce
- signal(int signum, handler sighandler_t);
- sigaction(int signum, const struct sigaction *act,struct sigaction *oldact);.
Tyto funkce vyžadují, aby byl do vašeho C kódu zahrnut header signal.h. Poskytl jsem jednoduchý příklad signal
funkce níže s komentáři.
#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;
}
Poznámka:měli byste volat pouze bezpečné/autorizované funkce v obslužném programu signálu. Vyhněte se například volání printf v obslužném programu signálu.
Tento kód můžete zkompilovat pomocí gcc a spustit jej z shellu. V kódu je nekonečná smyčka a bude běžet, dokud neodešlete SIGINT
signál stisknutím Ctr + C .
Můžete použít makro signálu.
Zde je příklad, jak se s tím vypořádat:
#include <signal.h>
#include <stdio.h>
void sigint(int a)
{
printf("^C caught\n");
}
int main()
{
signal(SIGINT, sigint);
for (;;) {}
}
Ukázkový výstup:
Ethans-MacBook-Pro:~ phyrrus9$ ./a.out
^C^C caught
^C^C caught
^C^C caught
^C^C caught
^C^C caught
Zadáním Ctrl C normálně způsobí, že shell odešle SIGINT
k vašemu programu. Přidejte obslužnou rutinu pro tento signál (prostřednictvím signal(2)
nebo sigaction(2)
) a můžete si dělat, co chcete, když stisknete Ctrl C je stisknuto.
Případně, pokud vám záleží pouze na tom, abyste provedli vyčištění před ukončením programu, nastavte obslužný program ukončení pomocí atexit(3)
může být vhodnější.