linux python守护进程,[转] 使用Python写Linux的守护进程(daemon)

A simple unix/linux daemon in Python

http://www.jejik.com/articles/2007/02/a_simple_unix_linux_daemon_in_python/

by Sander Marechal

I've

written a simple Python class for creating daemons on unix/linux

systems. It was pieced together for various other examples, mostly

corrections to various Python Cookbook

articles and a couple of examples posted to the Python mailing lists.

It has support for a pidfile to keep track of the process. I hope it's

useful to someone.

Below is the Daemon class. To use it, simply subclass it and implement the run() method.

import sys, os, time, atexit

from signal import SIGTERM

class Daemon:

"""

A generic daemon class.

Usage: subclass the Daemon class and override the run() method

"""

def __init__(self, pidfile, stdin='/dev/null', stdout='/dev/null', stderr='/dev/null'):

self.stdin = stdin

self.stdout = stdout

self.stderr = stderr

self.pidfile = pidfile

def daemonize(self):

"""

do the UNIX double-fork magic, see Stevens' "Advanced

Programming in the UNIX Environment" for details (ISBN 0201563177)

http://www.erlenstar.demon.co.uk/unix/faq_2.HTML#SEC16

"""

try:

pid = os.fork()

if pid > 0:

# exit first parent

sys.exit(0)

except OSError, e:

sys.stderr.write("fork #1 failed: %d (%s)\n" % (e.errno, e.strerror))

sys.exit(1)

# decouple from parent environment

os.chdir("/")

os.setsid()

os.umask(0)

# do second fork

try:

pid = os.fork()

if pid > 0:

# exit from second parent

sys.exit(0)

except OSError, e:

sys.stderr.write("fork #2 failed: %d (%s)\n" % (e.errno, e.strerror))

sys.exit(1)

# redirect standard file descriptors

sys.stdout.flush()

sys.stderr.flush()

si = file(self.stdin, 'r')

so = file(self.stdout, 'a+')

se = file(self.stderr, 'a+', 0)

os.dup2(si.fileno(), sys.stdin.fileno())

os.dup2(so.fileno(), sys.stdout.fileno())

os.dup2(se.fileno(), sys.stderr.fileno())

# write pidfile

atexit.register(self.delpid)

pid = str(os.getpid())

file(self.pidfile,'w+').write("%s\n" % pid)

def delpid(self):

os.remove(self.pidfile)

def start(self):

"""

Start the daemon

"""

# Check for a pidfile to see if the daemon already runs

try:

pf = file(self.pidfile,'r')

pid = int(pf.read().strip())

pf.close()

except IOError:

pid = None

if pid:

message = "pidfile %s already exist. Daemon already running?\n"

sys.stderr.write(message % self.pidfile)

sys.exit(1)

# Start the daemon

self.daemonize()

self.run()

def stop(self):

"""

Stop the daemon

"""

# Get the pid from the pidfile

try:

pf = file(self.pidfile,'r')

pid = int(pf.read().strip())

pf.close()

except IOError:

pid = None

if not pid:

message = "pidfile %s does not exist. Daemon not running?\n"

sys.stderr.write(message % self.pidfile)

return # not an error in a restart

# Try killing the daemon process

try:

while 1:

os.kill(pid, SIGTERM)

time.sleep(0.1)

except OSError, err:

err = str(err)

if err.find("No such process") > 0:

if os.path.exists(self.pidfile):

os.remove(self.pidfile)

else:

print str(err)

sys.exit(1)

def restart(self):

"""

Restart the daemon

"""

self.stop()

self.start()

def run(self):

"""

You should override this method when you subclass Daemon. It will be called after the process has been

daemonized by start() or restart().

"""

And here is an example implementation. It implements the daemon as well

as it's controlling client. Simply invoke this script with start, stop

or restart as it's first argument.

#!/usr/bin/env python

import sys, time

from daemon import Daemon

class MyDaemon(Daemon):

def run(self):

while True:

time.sleep(1)

if __name__ == "__main__":

daemon = MyDaemon('/tmp/daemon-example.pid')

if len(sys.argv) == 2:

if 'start' == sys.argv[1]:

daemon.start()

elif 'stop' == sys.argv[1]:

daemon.stop()

elif 'restart' == sys.argv[1]:

daemon.restart()

else:

print "Unknown command"

sys.exit(2)

sys.exit(0)

else:

print "usage: %s start|stop|restart" % sys.argv[0]

sys.exit(2)

That's it! I hope this is of some use to someone. Happy coding!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值