这是我正在使用的守护进程类
它是一个基类,我想从另一个控制器文件中生成2个单独的守护进程
class Daemon:
"""A generic daemon class.
Usage: subclass the daemon class and override the run() method."""
def __init__(self, pidfile,outfile='/tmp/daemon_out',errfile='/tmp/daemon_log'):
self.pidfile = pidfile
self.outfile = outfile
self.errfile = errfile
def daemonize(self):
"""Deamonize class. UNIX double fork mechanism."""
try:
pid = os.fork()
if pid > 0:
# exit first parent
sys.exit(0)
except OSError as err:
sys.stderr.write('fork #1 failed: {0}\n'.format(err))
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 as err:
sys.stderr.write('fork #2 failed: {0}\n'.format(err))
sys.exit(1)
# redirect standard file descriptors
sys.stdout.flush()
sys.stderr.flush()
si = open(os.devnull, 'r')
so = open(self.outfile, 'a+')
se = open(self.errfile, 'a+')
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())
with open(self.pidfile,'w+') as f:
f.write(pid + '\n')
#method for removing the pidfile before stopping the program
#remove the commented part if you want to delete the output & error file before stopping the program
def delpid(self):
os.remove(self.pidfile)
#os.remove(self.outfile)
#os.remove(self.errfile)
def start(self):
"""Start the daemon."""
# Check for a pidfile to see if the daemon already runs
try:
with open(self.pidfile,'r') as pf:
pid = int(pf.read().strip())
except IOError:
pid = None
if pid:
message = "pidfile {0} already exist. " + \
"Daemon already running?\n"
sys.stderr.write(message.format(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:
with open(self.pidfile,'r') as pf:
pid = int(pf.read().strip())
except IOError:
pid = None
if not pid:
message = "pidfile {0} does not exist. " + \
"Daemon not running?\n"
sys.stderr.write(message.format(self.pidfile))
return # not an error in a restart
# Try killing the daemon process
try:
while 1:
os.kill(pid, signal.SIGTERM)
time.sleep(0.1)
except OSError as err:
e = str(err.args)
if e.find("No such process") > 0:
if os.path.exists(self.pidfile):
os.remove(self.pidfile)
else:
print (str(err.args))
sys.exit(1)
def restart(self):
"""Restart the daemon."""
self.stop()
self.start()
def run(self):
"""override this method when you subclass Daemon.
It will be called after the process has been daemonized by
start() or restart()."""
这是我在不同文件中使用的代码
在这个文件中,我将守护进程类从单独的类扩展到&覆盖run()方法。
#! /usr/bin/python3.6
import sys, time, os, psutil, datetime
from daemon import Daemon
class net(Daemon):
def run(self):
while(True):
print("net daemon : ",os.getpid())
time.sleep(200)
class file(Daemon):
def run(self):
while(True):
print("file daemon : ",os.getpid())
time.sleep(200)
if __name__ == "__main__":
net_daemon = net(pidfile='/tmp/net_pidFile',outfile='/tmp/network_out.log',errfile='/tmp/net_error.log')
file_daemon = file(pidfile='/tmp/file_pidFile',outfile='/tmp/filesys_out.log',errfile='/tmp/file_error.log')
if len(sys.argv) == 2:
if 'start' == sys.argv[1]:
net_daemon.start()
file_daemon.start()
elif 'stop' == sys.argv[1]:
file_daemon.stop()
net_daemon.stop()
elif 'restart' == sys.argv[1]:
file_daemon.restart()
net_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)
运行start()方法的第一个类当前正在运行& 现在只有网守护进程工作如何使2个类产生2个单独的守护进程?
答案 0 :(得分:0)
这里真正的问题是您为所需的任务选择了错误的代码。你问的问题"我如何用这种电锯敲击钉子?"在这种情况下,它甚至不是专业生产的带有使用说明书的锯,它是一个自制的锯,你发现在某人的车库里,由一个可能知道他是什么的人建造的正在做但你确实无法确定,因为你不知道他在做什么。
您抱怨的最近问题是daemonize
:
try:
pid = os.fork()
if pid > 0:
# exit first parent
sys.exit(0)
第一次调用它时,父进程退出。这意味着父进程永远不会启动第二个守护进程,或者执行其他任何操作。
对于可由单独程序管理的自我守护程序,这正是您想要的。 (无论是否正确获取所有细节,我都不知道,但基本理念绝对正确。)
对于生成守护进程的管理程序,这正是您不想要的。那就是你要写的东西。所以这是工作的错误工具。
但是任务 非常不同。如果你了解自己正在做什么(并且打开你的Unix Network Programming
副本 - 没有人能够很好地理解这些东西,以便将它们从头脑中移开),你可以将其转换为另一个。这可能是一个有用的练习,即使对于任何实际的应用程序,我也只是在PyPI上使用一个经过良好测试,记录良好,维护良好的库。
如果您只是用sys.exit(0)
替换父进程中发生的return True
调用(而不是中间子进程中发生的调用!),会发生什么? (好吧,您可能还希望用sys.exit(1)
替换父级中的return False
或者引发某种异常。)然后daemonize
不再对您进行守护,而是生成一个守护进程,报告是否成功。这是你想要的,对吗?
不保证它能完成所有其他事情(而且我打赌它不会),但它确实解决了你所询问的具体问题。
如果在此之后没有明显的错误,下一步可能是阅读PEP 3143(这非常好,将史蒂文斯的所有细节翻译成Python术语,并确保他们和#39;了解21世纪的Linux和BSD的最新信息并提出运行测试的清单,然后运行它们以查看不太明显的事情,你仍然会出错。