Linux信号signal処理メカニズム3


前の2節では,信号に関するほとんどの知識を紹介した.このセクションでは、これらのシステム呼び出しについて説明します.ここで、システム呼び出しsignalは、ある信号を設定するためのプロセスの処理方法であり、システム呼び出しkillは、指定されたプロセスに信号を送信するために使用される.この2つの呼び出しは、信号の基本的な動作を形成することができる.後の2つの呼び出しpauseとalarmは、信号によって実現されるプロセス一時停止とタイマであり、呼び出しalarmは、プロセスタイマに信号によって通知される.ここでは、この2つの呼び出しについて説明します.
1、signalシステム呼び出し
システム呼び出しsignalは、ある信号の処理方法を設定するために使用される.呼び出し宣言のフォーマットは次のとおりです.
        void (*signal(int signum, void (*handler)(int)))(int);
呼び出しを使用するプロセスに次のヘッダファイルを追加します.
        #include
上記の宣言フォーマットは複雑ですが、使い方が不明な場合は、次のようなタイプの定義フォーマットで使用することもできます(POSIXの定義).
        typedef void (*sighandler_t)(int);
        sighandler_t signal(int signum, sighandler_t handler);
しかし、このフォーマットは異なるシステムで異なるタイプ定義があるので、このフォーマットを使用するには、オンラインマニュアルを参照したほうがいいです.
呼び出しでは、パラメータsignumは、処理方法を設定する信号を示す.2番目のパラメータhandlerは処理関数または
        SIG_IGN:パラメータsignumが示す信号を無視します.
        SIG_DFL:復元パラメータsignumで示す信号の処理方法がデフォルトです.
信号処理ルーチンに伝達される整数パラメータは信号値であり、1つの信号処理ルーチンが複数の信号を処理することができる.システム呼び出しsignal戻り値は、指定信号signumの前回の処理ルーチンまたはエラー時に返されるエラーコードSIG_であるERR.簡単な例を見てみましょう.

        #include <signal.h>
        #include <unistd.h>
        #include <stdio.h>
        void sigroutine(int dunno) { /*       ,  dunno         */
        switch (dunno) {
        case 1:
        printf("Get a signal -- SIGHUP ");
        break;
        case 2:
        printf("Get a signal -- SIGINT ");
        break;
        case 3:
        printf("Get a signal -- SIGQUIT ");
        break;
        }
        return;
        }

        int main() {
        printf("process id is %d ",getpid());
        signal(SIGHUP, sigroutine); //*              
        signal(SIGINT, sigroutine);
        signal(SIGQUIT, sigroutine);
        for (;;) ;
        }

ここで、信号SIGINTは、Ctrl−Cが押下され、信号SIGQUITはCtrl−が押下されて発行される.プログラムの実行結果は次のとおりです.
        localhost:~$ ./sig_test
        process id is 463
Get a signal-SIGINT//Ctrl-Cを押した結果
Get a signal-SIGHUIT//Ctrlを押すと結果が得られます
//Ctrl-zを押してプロセスをバックグラウンドに配置
        [1]+ Stopped ./sig_test
        localhost:~$ bg
        [1]+ ./sig_test &
localhost:~$kill-Hop 463//プロセスにSIGHUP信号を送信
        localhost:~$ Get a signal – SIGHUP
kill-9 463//プロセスにSIGKILL信号を送信し、プロセスを終了する
        localhost:~$
2、killシステム呼び出し
システム呼び出しkillは、プロセスに信号を送信するために使用されます.呼び出し宣言のフォーマットは次のとおりです.
        int kill(pid_t pid, int sig);
呼び出しを使用するプロセスに次のヘッダファイルを追加します.
        #include
        #include
システム呼び出しは、任意のプロセスまたはプロセスグループに任意の信号を送信するために使用することができる.パラメータpidが正数である場合、呼び出しは、pidというプロセス番号のプロセスに信号sigを送信する.pidが0に等しい場合、信号sigは、現在のプロセスが属するプロセスグループ内のすべてのプロセスに送信される.パラメータpidが−1に等しい場合、信号sigは、プロセス1およびそれ自体を除くすべてのプロセスに送信される.パラメータpidが−1未満の場合、信号sigはプロセスグループ−pidに属するすべてのプロセスに送信される.パラメータsigが0の場合、信号は送信されません.この呼び出しが正常に実行された場合、戻り値は0です.エラーが発生した場合は、-1を返し、対応するエラーコードerrnoを設定します.次に、返される可能性のあるエラー・コードを示します.
EINVAL:指定された信号sigが無効です.
ESRCH:パラメータpidで指定されたプロセスまたはプロセスグループは存在しません.プロセス・テーブル・アイテムに存在するプロセスは、waitによって回収されていないが、実行が終了した硬直したプロセスである可能性があります.
EPERM:プロセスはこの信号を指定した受信信号のプロセスに送信する権限がありません.1つのプロセスがプロセスpidに信号を送信することを許可される場合、root権限、または呼び出されたプロセスを発行するUIDまたはEUIDは、指定された受信プロセスのUIDまたは保存ユーザID(savedset-user-ID)と同じである必要があるからである.パラメータpidが−1未満、すなわち信号が1つのグループに送信される場合、エラーは、グループ内のメンバープロセスが信号を受信できないことを示す.
3、pauseシステム呼び出し
システムがpauseを呼び出す役割は、信号を待つことです.呼び出しの宣言形式は次のとおりです.
        int pause(void);
呼び出しを使用するプロセスに次のヘッダファイルを追加します.
        #include
この呼び出しは、1つの信号が受信されるまで、呼び出しを発行するプロセスをスリープさせる.呼び出しは常に-1を返し、エラーコードをEINTR(信号を受信)に設定します.簡単な例を次に示します.

         #include <unistd.h>
        #include <stdio.h>
        #include <signal.h>
        void sigroutine(int unused) {
        printf("Catch a signal SIGINT ");
        }

        int main() {
        signal(SIGINT, sigroutine);
        pause();
        printf("receive a signal ");
        }

この例では、プロセスが信号を待っているため、Ctrl−Cを押すと信号がキャプチャされ、pauseが待機状態を終了するため、プログラムが実行を開始する.