understanding linux kernel 輪読会 第9回 シグナル
TRANSCRIPT
LINUX 輪読会 第 9 回 シグナルY.MURASE
シグナルって何でしたっけ• プロセス間通信の 1 手段• kill(2) で他のプロセスに通知したり• なんかやらかした時にカーネルから通知されたりする• 基本的渡されるのはシグナル番号だけ• 通知されたプロセスはシグナルハンドラを起動して対処する• かデフォルトの動作
歴史的経緯• Unix v2 で追加されたシステムコール
• quit (= SIGQUIT)
• intr (= SIGINT)
• emit (= SGEMT)
• ilgins (= SIGFPE)
• ここらへんを整理するために v4 で signal やら kill が導入• もともとは異常が起きた時に通知するための仕組みだった• POSIX で汎用に拡張される
一覧
• x86 だとシグナルは 64 個ある• これを見る http://goo.gl/GhJhrC• ( 何故アーキテクチャ依存? )
リアルタイムシグナル : 背景• シグナルは生成と配送の二段階で通知される• 生成 : シグナルを相手のプロセスのデータ構造にぶち込む• 配送 : 自分の所に来たシグナルを確認して対応する
• 従来のシグナルでは生成と配送の回数が一致しないかも• 短い期間に SIGSEGV が二回来るとか
• シグナルの配送順序に規定がない
リアルタイムシグナル• → 新たにリアルタイムシグナルを導入• 生成されたシグナルが配送されることを保証• 小さいシグナル番号ほど優先度が高い• シグナル番号だけでなくより詳細な siginfo_t 構造体も渡される
• シグナル番号は SIGRTMIN...SIGRTMAX の範囲• どういう意味かはアプリケーション依存• 従来のシグナルは 1...SIGRTMIN-1 に割り当て
その他• 同期 / 非同期
• 同期:対象はスレッド (SIGSEGV, SIGILL)
• 非同期:対象はスレッドグループ (SIGINT, kill による配送 )
• どれかが対処する• シグナルハンドラ
• シグナルに対処するための関数• スレッドグループ間で共有• 特定のシグナル (SIGKILL, SIGSTOP) はデフォルトから変更できない
• シグナルマスク• 配送されたらまずいシグナルを保留させる• スレッドが個別に持つ
実装を見てみよう
データ構造
• task_struct にある• /include/linux/sched.h:1468
シグナルの生成• send_signal: /kernel/signal.c:1127• リアルタイムでなく既に生成済みなら終了 (1045)
• SIGSTOP, SIGKILL ならビットだけ立てて終了 (1053)
• キューに追加するための領域を確保 (1070)
• 成功したらキューに繋いで初期化• 失敗したら
• リアルタイムシグナルは生成の失敗を通知• 従来のシグナルは「キュー繋げなかったよ」と通知 ( 生成自体は成功扱い )
• 最後にビットを立てて終了
シグナルの配送• do_notify_resume(/arch/x86/kernel/signal.c:739)
• プロセスがユーザー空間に復帰する直前に呼び出される ( らしい )
• do_signal(699)• get_signal(/kernel/signal.c:2181)
• ここでシグナルを取り出す (2251)
• デフォルト動作はここで実行されるらしい (2280)
• handle_signal(630)
• setup_rt_frame(610) でレジスタの退避とスタックフレームの作成• コンテクストスイッチを生じないので専用の関数を定義しているっぽい
• シグナルハンドラはユーザ空間で実行• シグナルハンドラが終了したら sigreturn で戻ってくる
シグナルまとめ• 段階的に拡張されてきた歴史• 異常通知• 従来のシグナル• リアルタイムシグナル
• ある程度一貫性があるようなないような• コードは割とわかりやすい
余談 パイプ• みんなパイプ実装したから使い方わかるよね?• int pipe2(int pipefd[2], int flags)
• pipe2 が実行されると• 一つの inode オブジェクト• 二つのファイル• パイプバッファ
• read/write は最終的にここへの操作に行き着く
余談 PLAN9 のはなし• Plan9 にはシグナルはない ( 代わりに note)
• kill 関数 (not systemcall)• https://goo.gl/ib9jVN
• 実際には /proc/[pid]/note に文字列を書き込んでいる• cf: http://goo.gl/IrftTG Plan9 - /sys/man/2/notify
• なんか Plan9 は色んなものをファイルに抽象化してるんだって
余談 WINDOWS の IPC
• https://goo.gl/IOVgy2 InterProcess Communication - MSDN
参考 URL
• http://goo.gl/jW3Rp0 シグナルの誕生 - Plan9日記• http://goo.gl/GhJhrC Linux のシグナルまとめ