Ctr + C を押したとき 、オペレーティングシステムはプロセスにシグナルを送信します。多くのシグナルがあり、そのうちの 1 つが SIGINT です。 SIGINT (「プログラム割り込み」) は終了シグナルの 1 つです。
終了シグナルにはさらにいくつかの種類がありますが、SIGINT の興味深い点は、プログラムで処理 (キャッチ) できることです。 SIGINT のデフォルトのアクションは、プログラムの終了です。つまり、プログラムがこのシグナルを明確に処理しない場合、Ctr + C を押すと、 プログラムはデフォルトのアクションとして終了します。
シグナルのデフォルト アクションを変更するには、キャッチするシグナルを登録する必要があります。 C プログラム (少なくとも POSIX システムでは) にシグナルを登録するには、2 つの関数があります
<オール>
これらの関数では、ヘッダー signal.h を C コードに含める必要があります。 signal
の簡単な例を提供しました コメント付きの以下の関数。
#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;
}
注:シグナル ハンドラーでは、安全な/承認された関数のみを呼び出す必要があります。たとえば、シグナル ハンドラで printf を呼び出さないようにします。
このコードを gcc でコンパイルし、シェルから実行できます。コードには無限ループがあり、SIGINT
を送信するまで実行されます。 Ctr + C を押して信号を送る .
シグナル マクロを使用できます。
対処方法の例を次に示します:
#include <signal.h>
#include <stdio.h>
void sigint(int a)
{
printf("^C caught\n");
}
int main()
{
signal(SIGINT, sigint);
for (;;) {}
}
出力例:
Ethans-MacBook-Pro:~ phyrrus9$ ./a.out
^C^C caught
^C^C caught
^C^C caught
^C^C caught
^C^C caught
Ctrl を入力 C 通常、シェルは SIGINT
を送信します。 あなたのプログラムに。そのシグナルのハンドラーを追加します (signal(2)
経由) または sigaction(2)
)、そして Ctrl で好きなことをすることができます C
または、プログラムが終了する前にクリーンアップを行うことだけを考えている場合は、atexit(3)
を介して終了ハンドラーを設定します。 より適切かもしれません。