読者です 読者をやめる 読者になる 読者になる

プログラミング Erlang 捕捉不可終了シグナル

プログラミングErlang

プログラミングErlang

終了シグナル

  • 終了シグナルの実体は次のタプル {'EXIT',Pid,Why}
  • Erlangのプロセス同士はlink/1によってリンクすることにより、互いのプロセスに終了シグナルを送信することができる
  • ただし、終了シグナルを捕捉して処理するためには、process_flag(trap_exit,true)を評価することによって通常のプロセスをシステムプロセスにする必要がある
  • 終了シグナルはreceive節により捕捉する
  • 終了シグナルを意図的に発生させるにはexit/1exit/2を評価する
    • exit/1は、リンクセット(該当のプロセスにリンクされているプロセス群)に対して終了シグナルをブロードキャストして、プロセスを終了する
    • exit/2は、あるプロセスに対して終了シグナルをユニキャストして、プロセスを終了せず処理を継続する
  • 終了シグナルは大きく分けて、normal、kill、killed、実行時エラー*1などがある*2

normal

  • 捕捉可能だが通常のプロセスでは無視される
  • プロセスが(正常)終了する際にも送信される

kill/killed

  • exit/1によるkill終了シグナル送信ではシステムプロセスが捕捉して任意の処理が可能だが、exit/2によるkill終了シグナル送信ではシステムプロセスでも捕捉不可で必ず殺される
  • 殺されたプロセスはkilled終了シグナルをリンクセットに対してブロードキャストする

実行時エラー

  • 通常のプロセスは殺されるが、システムプロセスは捕捉して任意の処理が可能
  • 殺されたプロセスは、該当終了シグナルをリンクセットに対してブロードキャストする
  • killed終了シグナルも同様の動作となる

コード検証

7> edemo1:start(true, normal).
  • cの分岐の最後のパターンnormal->がマッチして、case式の評価結果はtrueとなりcは正常終了する
  • trap_exit=trueで捕捉しているbに{'EXIT',Pid,normal}が送信される
8> edemo1:start(true, {die,kill}).
  • cがexit/1でkill終了シグナルをブロードキャストすることでbにkill終了シグナルが送信され、cは終了する
  • trap_exit=trueで捕捉しているbに{'EXIT',Pid,kill}が送信され、bがそれを捕捉して(killedはブロードキャストせず)出力処理を実行する
6> edemo2:start(true, kill). 
  • cがexit/2でkill終了シグナルをbに対してユニキャストすることでbにkill終了シグナルが送信され、cは処理を継続してwait/1を実行して終了シグナル捕捉可能状態となる
  • trap_exit=trueで捕捉しているbにexit/2によりkill終了シグナルが送信されたため、bはこれを捕捉できず殺されて、killed終了シグナルをリンクセットに対してブロードキャストすることで、killed終了シグナルはaとcに送信される
  • trap_exit=trueで捕捉しているaとcはkilled終了シグナルを捕捉して出力処理を実行する

コード例

*1:0除算時に発生するbadarithなど

*2:自分の理解のために対象を絞っています...