理系学生日記

おまえはいつまで学生気分なのか

Process Termination

プロセスの終了方法は大きく分けると以下のように分けられる。

  • exit 関数の呼び出し
  • main 関数の終了
  • シグナルに対する反応としての異常終了

異常終了を引き起こすシグナルとしては、SIGBUS、SIGSEGV、SIGFPE などがある。SIGINT は Ctrl + C の押下で送信されるし、SIGKILL は kill コマンドで送信され、ともにプロセスを終了させる。abort 関数を呼ぶと、自身に対して SIGABRT シグナルを飛ばし、core ファイルを吐いて異常終了する。
これらのシグナルは kill コマンドで送信できるが、プログラムから kill 関数を呼びだすことでも可能である。kill の第一引数は pid、第二引数がシグナル番号となっている。

慣習として、exit の引数 (あるいは main 関数からの戻り値)はプログラムが正常に終了したかを示す。0 は正常終了を示し、0 以外はエラーが発生したことを示す。exit 関数の引数は int であるが、Linux は 32 bit の戻り値を記憶しない。実際には、0 から 127 の数字を返すべきである。128 以上の戻り値には特別な意味があり、シグナルで終了したプロセスは 128 + シグナル番号を返すからである。

プロセスの終了を待つ

fork を使った場合、Linux では親、子のプロセスの実行順序は予測できない。しかし、親プロセスが子プロセスの終了を待った方が良い場合も存在する。このようなケースは、wait 系システムコールによって解決できる。この関数はプロセスの終了を待ち、そのプロセスの終了に感する情報を取得することを可能とする。

wait システムコールは子プロセスのいずれかが終了するまでブロックする。いずれかが終了すると、引数に与えた int へのポインタ経由で子プロセスがどう終了したのかを表す整数値を返却する。この返却値に対して WIFEXITED マクロを呼び出すと、子プロセスが正常終了したかがどうかが判断できる。シグナルによって異常終了したプロセスに対しては WTERMSIG マクロを呼び出すことでシグナル番号を抽出することができる。

同様のシステムコールとしては他に、特定 pid を持つプロセスを待つ waitpid、子プロセスの CPU の統計も返す wait3 などがある。