#!/usr/bin/python
# encoding: utf-8
# usage:启动: python some_control.py start
# 关闭: python some_control.py stop
# 状态: python some_control.py status
# 重启: python some_control.py restart
# 查看: ps -ef | grep some_control
import atexit
import os
import sys
import time
import json
import signal
import config
import datetime
import threading
import traceback
class Daemon:
'''
stderr 表示错误日志文件绝对路径, 收集启动过程中的错误日志
save_path 表示守护进程pid文件的绝对路径
'''
def __init__(self, save_path, stdin=os.devnull, stdout=os.devnull, stderr=os.devnull, home_dir='.', umask=022):
self.stdin = stdin
self.stdout = stdout
self.stderr = stderr
self.pidfile = save_path # pid文件绝对路径
self.home_dir = home_dir
self.umask = umask
self.daemon_alive = True
# print "stdin:%s, stdout:%s, stderr:%s, pidfile:%s" % (self.stdin, self.stdout, self.stderr, self.pidfile)
def daemonize(self):
try:
pid = os.fork()
if pid > 0:
sys.exit(0)
except OSError, e:
print('fork #1 failed: %d (%s)\n' % (e.errno, e.strerror))
sys.exit(1)
os.chdir(self.home_dir)
os.setsid()
os.umask(self.umask)
try:
pid = os.fork()
if pid > 0:
sys.exit(0)
except OSError, e:
print('fork #2 failed: %d (%s)\n' % (e.errno, e.strerror))
sys.exit(1)
def sig_handler(signum, frame):
self.daemon_alive = False
signal.signal(signal.SIGTERM, sig_handler)
signal.signal(signal.SIGINT, sig_handler)
atexit.register(self.del_pid)
pid = str(os.getpid())
file(self.pidfile, 'w+').write('%s\n' % pid)
print ('daemon process started ...pid:%s' % pid)
def get_pid(self):
try:
pf = file(self.pidfile, 'r')
pid = int(pf.read().strip())
pf.close()
except IOError:
pid = None
except SystemExit:
pid = None
return pid
def del_pid(self):
if os.path.exists(self.pidfile):
os.remove(self.pidfile)
def start(self):
print 'ready to starting ......'
'检查此进程是否已经存在'
pid = self.get_pid()
if pid:
msg = 'pid 文件 [%s] 已存在, 请检查进程是否已经运行!\n'
print(msg % self.pidfile)
sys.exit(1)
'启动守护进程'
self.daemonize()
self.run()
def stop(self):
print 'stopping ...'
pid = self.get_pid()
if not pid:
msg = 'pid 文件 [%s] 不存在. 请检查进程是否已经运行\n' % self.pidfile
sys.stderr.write(msg)
if os.path.exists(self.pidfile):
os.remove(self.pidfile)
return
'尝试停止进程'
try:
i = 0
while 1:
os.kill(pid, signal.SIGTERM)
time.sleep(0.1)
i = i + 1
if i % 10 == 0:
os.kill(pid, signal.SIGHUP)
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)
print 'Stopped!'
def restart(self):
self.stop()
self.start()
def is_running(self):
pid = self.get_pid()
# print(pid)
return pid and os.path.exists('/proc/%d' % pid)
def run(self):
'重写此函数'
print 'base class run()'
#继承Daemon对象
class CSomeControl(Daemon):
def __init__(self, name, save_path, stdin=os.devnull, stdout=os.devnull, stderr=os.devnull, home_dir='.',
umask=022):
Daemon.__init__(self, save_path, stdin, stdout, stderr, home_dir, umask)
self.name = name # 派生守护进程类的名称
def run(self):
print "守护进程业务"
'''
采用linux守护进程方式后台执行
'''
if __name__ == '__main__':
help_msg = 'Usage: python %s <start|stop|restart|status>' % sys.argv[0]
if len(sys.argv) != 2:
print help_msg
sys.exit(1)
if not os.path.exists("/logs/some"):
os.makedirs("/logs/some")
p_name = 'some_controld' # 守护进程名称
pid_fn = '/logs/some' + 'some_controld.pid' # pid文件的绝对路径
cp = CSomeControl(p_name, pid_fn)
#cp.run()
if sys.argv[1] == 'start':
cp.start()
elif sys.argv[1] == 'stop':
cp.stop()
elif sys.argv[1] == 'restart':
cp.restart()
elif sys.argv[1] == 'status':
alive = cp.is_running()
if alive:
print 'some_controld [%s] is running ......' % cp.get_pid()
else:
print 'some_controld [%s] stopped' % cp.name
else:
print 'invalid argument!'
print help_msg
Python 守护进程
最新推荐文章于 2024-05-06 21:12:00 发布