守护进程(Daemon)也称为精灵进程是一种生存期较长的一种进程。它们独立于控制终端并且周期性的执行某种任务或等待处理某些发生的事件。
他们常常在系统引导装入时启动,在系统关闭时终止。
os模块中的fork方法可以创建一个子进程。相当于克隆了父进程
os.fork()
子进程运行时,os.fork方法会返回0;
而父进程运行时,os.fork方法会返回子进程的PID号。
所以可以使用PID来区分两个进程:
#!/usr/bin/env python
#coding=utf8
from time import sleep
import os
try :
pid = os.fork()
except OSError, e:
pass
sleep( 30 )
运行代码,查看进程:
[root@localhost ~] # python test2.py &
[1] 2464
[root@localhost ~] # ps -l
F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD
4 S 0 2379 2377 0 80 0 - 28879 wait pts /1 00:00:00 bash
0 S 0 2464 2379 0 80 0 - 31318 poll_s pts /1 00:00:00 python
1 S 0 2465 2464 0 80 0 - 31318 poll_s pts /1 00:00:00 python
0 R 0 2466 2379 0 80 0 - 37227 - pts /1 00:00:00 ps
简单守护进程例子:
def main():
''' 程序要执行的逻辑代码 '''
pass
# 创建守护进程函数
def createDaemon():
''' 第一块(创建第一个子进程) '''
# fork 第一个子进程(如果fork成功,父进程自杀,只留下第一个子进程继续向下运行)
try :
if os.fork() > 0 :
sys.exit( 0 )
except OSError, error:
print '(fork第一个子进程失败)fork #1 failed: %d (%s)' % (error.errno, error.strerror)
sys.exit( 1 )
''' 第一块结束 '''
###### 第一个进程创建成功后,它的ppid = 1,已是一个守护里程了,但有些功能上还是有被限制。
###### 所以下面再来创建一个子进程。第二次创建的子进程限制就没那多了,有可能没有,所以最安全。
###### 下面来创建第二个子进程。
os.chdir( '/' ) # 把第一个子进程的工作目录切换到 / (根目录)
os.setsid() # 第一个子进程取得程序的权限
os.umask( 0 ) # 第一个子进程取得工作目录的所有操作(目录的rwx)
''' 第二块(创建第二个子进程) '''
# fork 第二个子进程(如果fork成功,第一个子进程自杀,只留下新创建的第二个子进程)
try :
pid = os.fork()
if pid > 0 :
print 'Daemon PID %d' % pid
sys.exit( 0 )
except OSError, error:
print '(fork第二个子进程失败)fork #2 failed: %d (%s)' % (error.errno, error.strerror)
sys.exit( 1 )
''' 第二块结束 '''
####### 通过上面两个 try 语句块,只留下了第二个子进程在运行了。这时第二个子进程的ppid=1。
####### 创建的第二个子进程,可以说是一个不受限的守护进程了。
# 重定向标准IO(因为只有第二个子进程在运行了,所以也就是指定整个程序的输入、输出、错误流)
# sys.stdout.flush() # 清除程序运行空间的输出流
# sys.stderr.flush() # 清除程序运行空间的错误流
# inputS = file("/dev/null", 'r') # 定义一个 inputS 文件对象
# outputS = file("/dev/null", 'a+') # 定义一个 outputS 文件对象
# errorS = file("/dev/null", 'a+', 0) # 定义一个 errorS 文件对象
# os.dup2(inputS.fileno(), sys.stdin.fileno()) # 把程序的输入流重定向到上面定义的 inputS 文件对象上。
# os.dup2(so.fileno(), sys.stdout.fileno()) # 把程序的 输出流 重定向到上面定义的 outputS 文件对象上。
# os.dup2(se.fileno(), sys.stderr.fileno()) # 把程序的 错误流 重定向到上面定义的 errorS 文件对象上。
main() # main函数为真正程序逻辑代码
if __name__ = = "__main__" :
if platform.system() = = "Linux" :
createDaemon()
else :
sys.exit()