These pages are written by only Japanese.

Welcom to My Diary.com
最新の日記タイトル一覧カテゴリ別タイトル一覧トップへ戻る〜

こんばんわ♪ 現在は4月30日(火)4時20分。 静寂が闇を包む頃です。


hns - 日記自動生成システム - Version 2.19.5 (色々 Fixed)

先月 2002年12月 来月
01 02 03 04 05 06 07
08 09 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
Namazu for hns による簡易全文検索です。
詳細は 詳細指定/ヘルプをご参照下さい。
検索式:

2002年12月30日(月)(自宅)

(自宅)

監視システム

朝起きて確認をしたところ、ディスクが溢れていました。
あわててデータをファイルサーバに退避しました…
ただ…
bash-2.05$ uptime
 6:55AM  up 1 day, 11:21, 1 user, load averages: 6.42, 6.18, 6.02
という状況では、バックアップ作業さえキャプチャーに悪影響を及ぼします。
バックアップ中に家の前でいたずらされると、その瞬間を見逃す可能性が増えますので、気軽にバックアップも出来ません。
続く

ゾンビ・プロセスについて

昨日の問題をきっかけに、いままで曖昧なままにしていた SIGCHLD とゾンビ・プロセスについて整理してみました。
恐らくツッコミどころ満載な説明だと思いますが、 間違いをそのまま覚えているのはつらいですので、 あえて無知を晒け出そうと思います。
尚、ゾンビは BSD よりの表現らしく、SYSV では defunct と呼ぶようです。 自分はとりあえずゾンビで呼び方を統一しますので、 その辺りは適当に読み替えて下さい。

仕組み:

一般に UNIX では、親が子プロセス(の終了)と同期を取る為に、
  • exit や C-c interrupt で終了した時等 *1 に、親プロセスに送られる SIGCHLD
  • 子プロセスの処理終了まで待つ wait システムコール
といった仕組みが用意されているのですが、
  • プロセスが死ぬと親プロセスに CHLD シグナルを送って自分はゾンビになる。 (処理系に応じてゾンビを作らない設定をする事で避ける事も可能)
  • ゾンビの子がいる時に親プロセスが wait を発行すると子プロセスは成仏する。
  • 親プロセスが死んだ場合は、init が代わりに処理をしてくれる。 (実は、自分はここの理解が曖昧です… daemon ライブラリを使っているせいでしょうか…)
という挙動をします。つまり、
親に先立ち子プロセスが死んだ場合は、子プロセスは水子(ゾンビ)として
自縛霊のようにプロセステーブルを占有して、親に (wait という)
お経を唱えてもらうまで成仏できません。	
お経 (wait) を忘れて、短命な子プロセスを生成し続ける無責任な親がいると、 プロセステーブルがゾンビで溢れて新たなプロセスが生成できなくなり、 (一般ユーザでは)ログインさえ出来なくなります。
一つのプロセスがシステム全体に悪影響を及ぼしますので、 fork を利用する際には、子プロセスを作り過ぎないというだけでなく、 ゾンビの処理にも気をつけなければなりません。

対策:

自分は、親子で同期を取る必要のない 放任主義的なプログラムを作成する時には、 CHLD シグナルの割り込みハンドラで wait を実行するルーチンを 設定しています。
先の例では、
$SIG{'CHLD'} = sub { wait(); };
といったコードを追加していますが、 それだけでは問題が生じる事があります。なぜなら、
  • 複数の子プロセスが同時に終了すると、 一つの SIGCHLD しか伝えられない。
つまり、一つの SIGCHLD の割り込みハンドラで一度 wait を実行したとしても、 取りこぼしが生じて、ゾンビが生じる可能性が残るからです。
この辺を care しないデーモンは DoS で簡単にサービス不能になります… の「シグナルの取りこぼしとwaitpid()システムコール」に実例が載っていますので 参考になると思います。
これは解決しないといけない問題ですが、 wait(2) は、単純に子プロセスが死ぬまで待ちますので、 死んだ子プロセスがいる時に呼ばないとブロックします。 *2 無条件で呼ぶとブロックする可能性があります。
その為、非同期( ブロックしない)指定が可能な wait である waitpid(2)wait3(2) 、 wait4(2) 等を使うのが定石のようです。
$SIG{'CHLD'} = sub { while(wait3() > 0) { } };
use POSIX ":sys_wait_h";
$SIG{'CHLD'} = sub { shift; while(waitpid(-1,&WNOHANG)> 0) { } };
このようにすれば、 wait3 *3 waitpid は、
  • ゾンビの子プロセスが残っている間は 処理したプロセスの pid を返す
  • ゾンビを処理しきった後はブロックせずに -1 を返すので while を抜ける
という挙動をしますので、残っているゾンビプロセスを一掃できます。

まとめ:

そういう訳で、自分は fork をして、 かつ 親子で同期を取る必要のないプログラムを書く時には、 呪文のように、先の wait3waitpid のコードを SIGCHLD ハンドラに設定する事にしています。
尚、 にあるように、SIG_IGN を設定すると、 システムが良きに計らってくれる処理系もありますし、 もしかしたら、それが主流派かもしれません。
ですが、(いささか古い FAQ ではありますが) を読むと、
POSIX では SIG_IGN に SIGCLD をセットした時の振舞いは規定されていないので、
POSIX 系をサポー トするようなプログラムには使うことができません。
とありますので、今のところ、SIGCHLD でSIG_IGN を利用せず、 自前でハンドラを用意する事にしています。

備考:

以上の話はゾンビ対策に限った場合の話でして、 BSD のマニュアルにある通り SIGCHLD はプロセスのステータス変化を親に通知するシグナルですので、suspend した時にも SIGCHLD が発生するようです。
# まだ確かめていません。
また、プロセスが生きていたとしても、上記のような状態変化がある場合は、 wait でブロックしないそうです。
とはいえ…
自分としては子プロセスに resume させたりといったプログラムと しばらく縁がなさそう …でもなかったりします… (汗……ですので、子プロセスの終了に限定した話をするのも意味があると思います。

追記 (2009/4/22):

google 経由で来られる方が多いので、少しまとめました。

*1: signal(7) のマニュアルを読むと、 Linux2.4 は「Child stopped or terminated」、 NetBSD1.6 ではより抽象的に「child status has changed」と記載されていて、 処理系によって説明が異なるようですので、 「〜等」と表現しました…
*2: ブロックしない条件が曖昧ですので、断言は避けます。
*3: Solaris2.x や Linux2.x、FreeBSD4.x で wait3 を使って来たのですが、 今回、NetBSD1.6 では wait3 が使えなかったので、より一般的な waitpid に 変更しました…

本当は怖い家庭の医学 - テレビ朝日

食事中、たまたま家の人がテレビをつけまして、久々に鑑賞しました。
テレビ朝日で「本当は怖い家庭の医学」という番組が放映されていまして、 メディカル・ホラーという題で、 虫歯や肥満等が悪化して死亡したり足を切るような例が次々と紹介されました。
それを見た自分は、 人は恐怖でしか動けない事を理解しました…
ですが…

その30分後には黒糖3度塗りのふがしを食べている自分がここにいます…
甘いものを食べ過ぎて無性に牛乳が飲みたくなるほどに…
# 喉元過ぎればなんとやら…

無線LAN カード

これ の続き
ADTEC のユーティリティー&ドライバーセットを uninstall したところ、 VAIO の内蔵無線 LAN の機能が復活しました。
ほっとしてます。

これで、1 日分だよ〜。

タイトル一覧
カテゴリ分類
Database
JXTA
Java
XML
awm
bookmark
keyword
memo
news
research
Powered by hns-2.19.5, HyperNikkiSystem Project