GNU/Linux >> Linux の 問題 >  >> Linux

Linux での Ctrl + C 割り込みイベント処理

Ctr + C を押したとき 、オペレーティングシステムはプロセスにシグナルを送信します。多くのシグナルがあり、そのうちの 1 つが SIGINT です。 SIGINT (「プログラム割り込み」) は終了シグナルの 1 つです。

終了シグナルにはさらにいくつかの種類がありますが、SIGINT の興味深い点は、プログラムで処理 (キャッチ) できることです。 SIGINT のデフォルトのアクションは、プログラムの終了です。つまり、プログラムがこのシグナルを明確に処理しない場合、Ctr + C を押すと、 プログラムはデフォルトのアクションとして終了します。

シグナルのデフォルト アクションを変更するには、キャッチするシグナルを登録する必要があります。 C プログラム (少なくとも POSIX システムでは) にシグナルを登録するには、2 つの関数があります

<オール>
  • signal(int signum, sighandler_t handler);
  • sigaction(int signum, const struct sigaction *act,struct sigaction *oldact);.
  • これらの関数では、ヘッダー 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) を介して終了ハンドラーを設定します。 より適切かもしれません。


    Linux
    1. PipeWire –Linuxでのオーディオとビデオの処理の改善

    2. UNIX / Linux:プロセスにシグナルを送信する 3 つの方法

    3. Linux シグナル – シグナル (SIGINT、SIGKILL、SIGSTOP など) をキャッチする C プログラムの例

    1. Linux シグナルの基礎 – パート I

    2. プログラムをキャンセルするコマンドの ctrl c と同等

    3. UNIX/Linux シグナル処理:SIGEV_THREAD

    1. Linux USB 接続/切断イベント

    2. Linux での複数スレッドによるシグナル処理

    3. Ctrl-C で Python C 拡張を中断できるようにする