Pythonでprefork型のデーモンを書く
Pythonのお勉強を兼ねて、先日 Cで書いた C言語でprefork型のデーモンを書く(3): デーモン化 - Sleepless geek in Seattle をPythonに移植してみた。
条件分岐、ループ、関数定義、ファイル操作、fork、wait、シグナルハンドラ、連想配列、などなど短いプログラムだけど、いろいろな要素が入っているのでなかなか良いサンプルになった。
#!/usr/bin/env python
import os
import sys
import signal
import time
MAX_CHILDREN=16
PID_FILE='/var/run/my_prefork_daemon.pid'
hash_children={}
def main():
#デーモン化
daemonize()
#プロセスIDを書いておく
write_pid()
#シグナルハンドラの登録
signal.signal(signal.SIGTERM, kill_all_children )
# 親プロセスのループ
# 子プロセスを監視して、子が死んだらすぐに新しい子プロセスを作成する
while True:
while len( hash_children )>=MAX_CHILDREN:
child_pid = os.wait()
del( hash_children[child_pid] )
pid = os.fork()
if pid == 0:
signal.signal( signal.SIGTERM, lambda sig,status:sys.exit(0) )
break
else:
#ハッシュテーブルに子プロセスのプロセスIDを保存しておく
hash_children[pid]=1
time.sleep(0.1)
# 子プロセスのループ
while True:
#ここがメインルーチンになる。
time.sleep(1)
def kill_all_children(sig, status):
for pid in hash_children.keys():
os.kill( pid, signal.SIGTERM )
os.exit(0)
def write_pid():
f = open(PID_FILE, mode='w');
f.write("%d" % os.getpid())
f.close()
def daemonize():
os.chdir("/")
try:
pid = os.fork()
if pid > 0:
sys.exit(0)
except OSError, e:
raise Exception, "%s [%d]" % (e.strerror, e.errno)
os.setsid()
os.umask(0)
sys.stdin = open('/dev/null', 'r')
sys.stdout = open('/dev/null', 'w')
sys.stderr = open('/dev/null', 'w')
if __name__ == "__main__":
main()
参考
C言語でprefork型のデーモンを書く(1): 非デーモン prefork サンプル - Sleepless geek in Seattle
C言語でprefork型のデーモンを書く(2): 非デーモン prefork シグナルハンドラ付き - Sleepless geek in Seattle
C言語でprefork型のデーモンを書く(3): デーモン化 - Sleepless geek in Seattle
C言語でprefork型のデーモンを書く(4): init スクリプト - Sleepless geek in Seattle