使用Python编写Linux系统守护进程需要以下步骤:
- 确定需要运行的任务
- 编写Python程序
- 编写启动守护进程的代码
- 编写守护进程的核心代码,使它可以在后台运行并自动重启
- 编写守护进程的停止代码
下面我们进入详细的攻略步骤:
1. 确定需要运行的任务
在编写Python守护进程之前,你需要确定需要运行的任务。比如,你的任务是每隔一段时间执行指定的Python脚本,将结果写入日志文件中。此时,你需要编写一个Python脚本,并将它交给你的守护进程来运行。
2. 编写Python程序
在确定你需要运行的任务之后,你需要编写Python程序来执行指定的任务。你可以使用Python内置的库,如os和time,来执行各种任务。
示例代码1:每隔5秒打印一次“hello world”
import time
while True:
print("hello world")
time.sleep(5)
示例代码2:每隔5秒执行一次脚本,并将结果写入日志文件
import os
import time
while True:
os.system("python script.py >> log.txt")
time.sleep(5)
3. 编写启动守护进程的代码
在编写守护进程之前,你需要编写一些代码来启动它。这可以是简单的脚本,如启动脚本,或者更观察守护进程执行并启动它的其他程序。要启动守护进程,请使用命令行或写一个启动脚本。
4. 编写守护进程的核心代码
在编写守护进程的核心代码时,你需要考虑以下几个方面:
- 如何使守护进程在后台运行
- 如何在发生意外情况时自动重启
- 如何停止守护进程
在下面的示例中,我们将编写一个简单的Python守护进程,它每隔一段时间执行一个脚本,并将结果写入日志文件中。
首先,我们需要导入所需的库:
import os
import sys
import time
import atexit
from signal import SIGTERM
然后,我们将创建一个Daemon类,它具有以下方法:
- init: 初始化守护进程
- daemonize: 让守护进程在后台运行
- run: 执行守护进程任务
- stop: 停止守护进程
class Daemon:
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):
# 从父进程脱离
try:
pid = os.fork()
if pid > 0:
sys.exit(0)
except OSError as e:
sys.stderr.write('fork #1 failed: %d (%s)\n' % (e.errno, e.strerror))
sys.exit(1)
os.chdir('/')
os.setsid()
os.umask(0)
# 从第二个子进程脱离
try:
pid = os.fork()
if pid > 0:
sys.exit(0)
except OSError as e:
sys.stderr.write('fork #2 failed: %d (%s)\n' % (e.errno, e.strerror))
sys.exit(1)
# 重定向标准文件描述符
sys.stdout.flush()
sys.stderr.flush()
si = open(self.stdin, 'r')
so = open(self.stdout, 'a+')
se = open(self.stderr, 'a+')
os.dup2(si.fileno(), sys.stdin.fileno())
os.dup2(so.fileno(), sys.stdout.fileno())
os.dup2(se.fileno(), sys.stderr.fileno())
# 写入pid文件
atexit.register(self.delpid)
pid = str(os.getpid())
with open(self.pidfile, 'w+') as f:
f.write(pid + '\n')
def delpid(self):
os.remove(self.pidfile)
def start(self):
# 检查pid文件是否存在,并且守护进程是否在运行
try:
with open(self.pidfile, 'r') as f:
pid = int(f.read().strip())
except IOError:
pid = None
if pid:
message = "pidfile %s already exist. Daemon already running?\n"
sys.stderr.write(message % self.pidfile)
sys.exit(1)
# 启动守护进程
self.daemonize()
self.run()
def stop(self):
# 从pid文件中获取pid,并杀死进程
try:
with open(self.pidfile) as f:
pid = int(f.read().strip())
except IOError:
pid = None
if not pid:
message = "pidfile %s does not exist. Daemon not running?\n"
sys.stderr.write(message % self.pidfile)
return
# 杀死进程
try:
while True:
os.kill(pid, SIGTERM)
time.sleep(0.1)
except OSError as e:
if e.errno == errno.ESRCH:
if os.path.exists(self.pidfile):
os.remove(self.pidfile)
else:
print(str(e))
sys.exit(1)
def restart(self):
self.stop()
self.start()
def run(self):
# 执行守护进程的任务
while True:
os.system("python script.py >> log.txt")
time.sleep(5)
5. 编写守护进程的停止代码
最后,我们需要编写守护进程的停止代码。这通常是一个简单的调用停止方法的脚本。
if __name__ == '__main__':
daemon = Daemon('/var/run/mydaemon.pid',
stdout='/tmp/mydaemon.log',
stderr='/tmp/mydaemon.log')
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)
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:使用Python编写Linux系统守护进程实例 - Python技术站