当我们希望一些Python代码在后台不断运行,同时保证它不会因为意外情况而终止,比如说退出或崩溃,那么这时候我们通常会使用“守护进程”的方式来达成这个目的。Python的os
模块提供了实现守护进程的方法,其中使用fork
来创建进程是一种相对简单的实现方式。
1. 使用fork创建守护进程步骤示例
以下是使用fork
来创建守护进程步骤示例:
import os, sys
# fork 子进程
pid = os.fork()
# 如果fork出错了,报错并退出程序
if pid < 0:
sys.exit("fork error")
# 如果是父进程,结束
if pid > 0:
sys.exit(0)
# 设置새的会话,并且设置进程组id为自己
os.setsid()
# 关闭输入
sys.stdin.close()
# 关闭输出
sys.stdout.close()
# 关闭错误输出
sys.stderr.close()
# 分离所有终端,变成一个真正意义上独立的进程
# 这时候就不会被控制终端以及其他的进程干扰了
# 下面的代码是一些后台运行的代码,可任意编写
while True:
pass
需要注意的是,这段代码在子进程中运行,将自己分离出控制终端和进程组,变成一个“守护”进程后,即可在后台运行。
2. 完整守护进程示例
以下是一个完整实践守护进程的例子:
import os, sys, time
def daemonize(stdin='/dev/null', stdout='/dev/null', stderr='/dev/null'):
"""
实现守护进程步骤函数
"""
try:
pid = os.fork()
if pid > 0:
#退出父进程
sys.exit(0)
except OSError as err:
sys.stderr.write('_fork #1 failed: {0}\n'.format(err))
sys.exit(1)
#修改当前工作目录
os.chdir('/')
#脱离文件输入输出
os.umask(0)
os.setsid()
try:
pid = os.fork()
if pid > 0:
#退出第一个子进程
sys.exit(0)
except OSError as err:
sys.stderr.write('_fork #2 failed: {0}\n'.format(err))
sys.exit(1)
#将输入输出指向空设备
sys.stdout.flush()
sys.stderr.flush()
si = open(stdin, 'r')
so = open(stdout, 'a+')
se = open(stderr, 'w')
#dup2函数原子化关闭和复制文件描述符
os.dup2(si.fileno(), sys.stdin.fileno())
os.dup2(so.fileno(), sys.stdout.fileno())
os.dup2(se.fileno(), sys.stderr.fileno())
#进入主循环
while True:
#这里写守护进程的代码
time.sleep(10)
if __name__ == '__main__':
daemonize('/dev/null', '/tmp/daemon_stdout.log', '/tmp/daemon_error.log')
这个函数接受三个文件路径名参数,stdin、stdout以及stderr,分别代表标准输入、标准输出和标准错误输出的文件路径,如果这些参数未指定,则它们将分别指向/dev/null
。在这个例子中,daemonize()
函数创建了一个守护进程,并在标准输入、标准输出和标准错误输出中记录日志。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:python使用fork实现守护进程的方法 - Python技术站