プロフィール

kosaki

Author:kosaki
連絡先はコチラ

ブログ検索
最近の記事
最近のコメント
最近のトラックバック
リンク
カテゴリー
月別アーカイブ
RSSフィード
FC2ブログランキング

スポンサーサイト このエントリーをはてなブックマークに追加

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。


スポンサー広告 | 【--------(--) --:--:--】 | Trackback(-) | Comments(-)

Linuxでプロセスの終了を知る方法はあるか? このエントリーをはてなブックマークに追加

ちょっと、おバカなタイトルで攻めてみる。

親プロセス以外が、プロセスの終了を通知してもらう方法はあるのか?
という話。

最初に聞いたとき、脊髄反射的に、いろいろあるよーーー。と思った
do_exit()を追うだけでも、

profile_task_exit()
profile_handoff_task()
proc_exit_connector()
security_task_free()

このぐらい見つかる。
んが、どいつもこいつも、task_struct終了時通知なので、スレッドが死ぬ度に通知が飛びやがるのである。

しかもexit処理はいくつも同時に走りうるので、通知関数で
thread_group_empty()やら tsk->signal->live==1 やらでチェックするのもウマくない
(チェックしている最中にどんどん状態が変わるから)

さて、どうしたものか


P.S
ところで、netlinkのプロセスの生成・終了を監視する機構って全然ドキュメントないんだけど、誰が何のためにいれたんでしょ??
需要があるかどうか分からんけど、今度手引書書こうかしらん


追記
待てよ・・・
profile_handoff_task()
security_task_free()
の2つは put_task_struct()から呼ばれているのだからして、
thread_group_leaderは必ず最後にPF_DEADに遷移する。の規則により
この2つでif(pid==tgid) と判定するだけかぁ??
今度試す。


追記2
KAMEさんから、すごく素朴な指摘をうけて、ああ、説明が足りんかったと反省。
もっと具体的に書く。

あるプロセスにスレッドが2ついたとする、それぞれのpid, tgidは以下


pid tgid
--------------------------
スレッドA 101 101
スレッドB 102 101


そうすると、上記Hookはプロセス終了時に2回呼ばれる(スレッドが2つあるから)
ところが、たとえば、profile_task_exit() でprintkデバッグしていると以下の2つのケースがありうる。

ケース1)
1.スレッドA profile_task_exit()
この時、tsk->signal->live==2
2.スレッドB profile_task_exit()
この時、tsk->signal->live==1

ケース2)
1.スレッドA profile_task_exit()
この時、tsk->signal->live==2
2.スレッドB profile_task_exit()
この時、tsk->signal->live==2

ケース2で何が起こっているかというと

1.スレッドA profile_task_exit()
この時、tsk->signal->live==2
2.スレッドB profile_task_exit()
この時、tsk->signal->live==2
3.スレッドA atomic_dec(tsk->signal->live)
4.スレッドB atomic_dec(tsk->signal->live)

のように、do_exit()が2つのスレッドでほぼ同時に呼ばれる事により、
(このような状態はdo_group_exit()を呼ぶだけで簡単に作り出せる)
Hook関数からは、signal->liveの参照カウンタが2->2->0と変化したかのようにみえてしまっている。と。

んで、POSIX的にはmain thread に対してpthread_exit()を呼ぶことはアリなので、そうするとmain threadが最初にdo_exit()で抜けてくるやもしれず、pid==tgidでは判定できず、かつ、参照カウンタも信用できず。うーむ。
というのがそもそもの悩みだったのですよ。

監視プロセスが1つだけなら、ユーザーランドからkill -0 で定期監視すればいいけど、おいらが作っているのはミドルウェアで、監視対象が100とか10000とか増えてくると定期監視はいまいちヤル気がしないというのもあって、カーネルから通知してくれる口はないものかしら。と思っていた。と
そういうわです。

分かりにくくてすいませんm(_ _)m
関連記事


linux | 【2006-12-11(Mon) 23:56:38】 | Trackback:(0) | Comments:(12)
コメント

終了監視するってことは監視対象のPIDがわかってて、監視対象のPIDかどうか判定すれば面倒ないんじゃないかなぁ。と言ってみる。
2006-12-11 月 19:04:15 | URL | KAME #- [ 編集]

KAMEさん>
本文の状況説明が不親切すぎたので、追記2に状況を書き足してみました。
これで元々の悩みが分かっていただけるかしら?
2006-12-12 火 07:26:42 | URL | kosaki #- [ 編集]

おおなるほど。明日考えてみよ。
2006-12-12 火 11:10:10 | URL | y-goto #- [ 編集]

ちなみに、NPTL前提で考えるとNPTLはラストスレッドのpthread_exit()に対して、exit()ではなくexit_group()を呼んでくれる親切設計なので、
if(t->signal->flags & SIGNAL_GROUP_EXIT)
が真となるときが、プロセス終了条件とみなしても無問題なんだけど、ここでは、もっと一般的な解はないの?
って事を考えています。

ミドルウェア作る立場からすると、ユーザがexitシステムコールを直接発行するだけで破綻するつくりはカッコよくないので。
2006-12-12 火 11:14:36 | URL | kosaki #- [ 編集]

(半分自前の)拡張シェルを作ってタスクランチャ経由でアプリ起動>SIGCHLDで監視がお手軽&汎用でいいかなぁ。ユーザから受けとッたコマンドをシェルからではなく、タスクランチャサーバから起動してしまう。
無理してカーネルでやることない気もします。このあたりのタスク管理強化した拡張シェルのうまいデザインは分散コンピューティング系(統合)環境のインプリにあるはず。
工数と相談ですが。
2006-12-12 火 19:26:14 | URL | KAME #- [ 編集]

KAMEさん>
アプリがfork-exec しないと仮定しているのは問題っす
2006-12-12 火 21:54:44 | URL | kosaki #- [ 編集]

そりゃまぁ、setpgid()呼ばれりゃ捕まえられませんが。カーネルでやることは最小限にして上位でリッチな処理をするのがいいと思います。>exitしたプロセスを全て捕まえて、ユーザランドで仕分けする等
2006-12-12 火 23:05:30 | URL | KAME #- [ 編集]

SEとかなら、自分が管理しているBOXに入っているアプリはこれとこれだけ。って言えるのでありなんでしょうね。それも。
2006-12-13 水 01:26:08 | URL | kosaki #- [ 編集]

ちなみに、put_task_struct()の延長の関数は ストックカーネルだと RCU でフリーされるのでタイミング的にうまくないかも。
というわけで、2.6.18系(あえてこう呼ぶ)では Documentation/accounting/taskstats.txt を使うのに一票。ちなみに 3000fork/s というログをみたことあるんで(運用中)注意。
2006-12-13 水 01:56:25 | URL | KAME #- [ 編集]

ああ、言外の意味にうすうす気がついてしまった・・・・
明日、話を聞きにいくっす(^-^;;
2006-12-13 水 05:20:31 | URL | kosaki #- [ 編集]

はじめまして
たまたまこのページを見つけたものですが。

inotify 使えないかな?
/proc/{PID}
を監視対象に追加して、削除されるのを待つとか。
2006-12-14 木 01:42:05 | URL | iz #- [ 編集]

うーむ、アリな気がする・・・
今使っているRHEL4だとinotifyないので、ちょっと遅くなるかもしれませんが、試してみて誤報告したいと思います m(_ _)m
2006-12-14 木 06:26:16 | URL | kosaki #- [ 編集]
  1. 無料アクセス解析
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。