C++を使用し、Linux GNU C Compilerを使用してコンパイルするアプリケーションを開発しています。ただし、ユーザーがスクリプトを中断するときに関数を呼び出したい CtrlC キー。私は何をすべきか?どんな答えでも大歓迎です。
を押すと Ctr + C、オペレーティングシステムは signal をプロセスに送信します。多くのシグナルがあり、そのうちの1つはSIGINTです。 SIGINT(「プログラム割り込み」)は終了シグナルの1つです。
終了シグナルにはさらにいくつかの種類がありますが、SIGINTの興味深い点は、プログラムで処理(キャッチ)できることです。 SIGINTのデフォルトアクションはプログラムの終了です。つまり、プログラムがこの信号を特に処理しない場合、次を押します。 Ctr + C プログラムはデフォルトのアクションとして終了します。
シグナルのデフォルトのアクションを変更するには、キャッチするシグナルを登録する必要があります。 (少なくともPOSIXシステムで)Cプログラムにシグナルを登録するには、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;
}
注:シグナルハンドラでは safe/authorized functions のみを呼び出す必要があります。たとえば、 シグナルハンドラでprintfを呼び出さないでください 。
このコードをgccでコンパイルして、シェルから実行できます。コードには無限ループがあり、を押してSIGINT
信号を送信するまで実行されます Ctr + C。
タイピング CtrlC 通常、シェルはSIGINT
をプログラムに送信します。そのシグナルのハンドラーを( signal(2)
または sigaction(2)
を介して)追加すると、いつでも好きなことができます CtrlC が押されます。
代わりに、プログラムが終了する前にクリーンアップのみを行う場合は、 atexit(3)
を使用して終了ハンドラーを設定する方が適切な場合があります。
シグナルマクロを使用できます。
対処方法の例を次に示します。
#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