Python 守护进程

import os
import sys
from time import sleep
try:
    pid = os.fork()
    if pid > 0: sys.exit(0) # Exit parent.
    pid = os.fork()

    os.setsid()
    os.chdir(self.curdir)
    os.umask(022)


if pid > 0: sys.exit(0) # Exit parent. except OSError, e: sys.stderr.write("fork failed: (%d) %s\n" % (e.errno, e.strerror)) sys.exit(1) while 1: sleep(1)

 

fork用户将当前进程分叉,即新建一个子进程,这样,运行完pid=os.fork()这条语句后,就有两个进程,这两个进程都会独自运行下面的代码,同时每个进程都有一个pid,子线程的pid为0

 派生一个守护进程后,通过while来实现该进程一直在后台运行

 

.ps -ajx 参数说明:ppid 父进程id,pid 进程id,pgid 进程组id,sid 会话期id
 
一个进程组包含多个进程,一个会话期包含多个进程组,一个会话期拥有一个终端,
如果在该终端输入退出(ctrl+c)命令,将关闭改会话期包含的所以进程
 
创建守护进程步骤
目的:使子进程不会拥有控制终端,即不要继承父进程的进程组id和会话组id,也就是使子进程成为进程组组长和会话组组长
1.创建子进程。fork产生子进程,由于有父进程,所以该子进程不会是进程组组长和会话期组长
2.脱离控制终端。通过setid方法,使子进程成为 新的会话期 组长,由于该会话期只有一个进程,所以该子进程也是进程组组长。这是改会话期组长是没有可控制终端的
3.禁止进程重新打开控制终端 。现在,进程已经成为无终端的会话组长,但它可以重新申请打开一个控制终端。可以通过使进程不再成为会话组长来禁止进程重新打开控制终端:
4.关闭打开的文件描述符
5.改变当前工作目录
6.重设文件创建掩码
7.从子进程中fork另一个子进程,该子进程不是进程组组长,也不是会话期组长,是真正的守护进程
 
为了更好地观察创建守护进程中,各种身份的变化,在这里做一个测试
测试代码:
#encoding=utf-8
__author__ = 'kevinlu1010@qq.com'

import os
import sys
from time import sleep
try:

    pid = os.fork()
    print '完成第一次fork'
    sleep(10)  #sleep1
    if pid > 0: sys.exit(0) # Exit first parent.

    os.setsid()
    print '执行setsid,使子进程成为会话期组长'
    sleep(10)  #sleep2

    os.chdir('/')
    os.umask(022)  #设置当前权限掩码,同时返回先前的权限掩码。
    print '完成修改工作目录和权限掩码'
    sleep(10)  #sleep3

    pid = os.fork()
    print '完成第二次fork'
    sleep(10)  #sleep4
    if pid > 0: sys.exit(0) # Exit first parent.

    print '守护进程启动完成'
    sleep(10)   #sleep5
except OSError, e:
    sys.stderr.write("fork  failed: (%d) %s\n" % (e.errno, e.strerror))
    sys.exit(1)

while 1:
    sleep(1)

这里一共有5个sleep,我在每个sleep都用ps -axj|grep python命令查看进程的id变化,分别为:
标题头:

父进程id  进程id  进程组id  会话期id

进程组或会话期的id与该进程组或会话期的组长的进程id相同

例如进程id是7000的进程,它的进程组id是6000,即7000所属的进程组的id是6000,该进程组的组长是进程id为6000的进程,会话期同理

sleep1:

第一个进程为父进程,第二个为子进程,他们有共同的进程组id和会话期id

 sleep2:
父进程退出,剩下子进程,通过setsid命令,使子进程成为进程组组长和会话期组长
 sleep3:
这个步骤id不会变化
sleep4:
子进程再fork一个子进程,之前的子进程变成父进程,父进程与子进程拥有共同的进程组id和会话期id,
 sleep5:
父进程退出,子进程既不是进程组组长也不是会话期组长,子进程与第一个父进程完全脱离关系,子进程没有控制终端,达到守护进程需要的条件
 

参考资料:http://www.01happy.com/python-fork-create-process/

http://blog.csdn.net/mr_jj_lian/article/details/7252222

 

posted @ 2014-04-23 11:51  Xjng  阅读(3907)  评论(0编辑  收藏  举报