ゾンビプロセスを作らないために
デーモンプロセスは,自分が起動されたシェルなど,外界から切り離すために,常駐処理をforkして親プロセスを終了させます. 通常の処理では,親プロセスは子プロセスの終了状態(終了ステータス)を監視しますが,デーモンプロセスは,常駐処理が動き始めると不要になります.このため,子プロセスの終了状態が必要ないことをシステムに宣言しなければなりません.そうすれば,常駐処理が終了しなくても親プロセスは終了してしまい,ゾンビプロセスとしてシステムに残ることはなくなります.
標準入出力
デーモンの動作を行うと,少なくとも stdin, stdout, stderr は必要なくなります.
Python では os.dup2 を使って標準入出力と標準エラー出力のファイル・ディスクリプタをクローズしなくちゃなりません。
out_log = file('/out/log/file/name', 'a+')
err_log = file('/err/log/file/name', 'a+', 0)
dev_null = file('/dev/null', 'r')
os.dup2(out_log.fileno(), sys.stdout.fileno())
os.dup2(err_log.fileno(), sys.stderr.fileno())
os.dup2(dev_null.fileno(), sys.stdin.fileno())シェル スクリプトのお約束
#!/bin/sh
exec </dev/null
exec >log.`date +%Y%m%d`.$$
exec 2>&1
renice +20 -p $$
echo [`date`]: start: $$
for f in *.gz; do
echo [`date`]: process: $f
out=${f/.gz/out.gz}
gzip -dc $f | nanka.py | gzip -c > $out
doneとくに標準入力を閉じておく (/dev/null にしておく) のは重要で、これをやり忘れると ssh で入ったときに ssh が止まってウンともすんともいわなくなってしまい、 SIGHUP を送って殺すという大変後味の悪い行為をしなければならない。これは ssh が仮想端末を見ているプロセスがすべて死ぬまで終わってくれないからである。 http://tabesugi.net/memo/2003/b2.html#142338
参考ページ
- デーモンプロセスの実像にせまる!デーモンプロセスのヒ・ミ・ツ http://www7a.biglobe.ne.jp/~tsuneoka/daemon/
- プログラムのデーモン化 http://pinka99.ddo.jp/nanao/work/daemon.html