ゾンビプロセスを作らないために

デーモンプロセスは、自分が起動されたシェルなどを外界から切り離すために、常駐処理を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


最終更新日: 2014年06月22日(日) / カテゴリー: プログラミング・ソフトウェア開発


Back to top