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