zoukankan      html  css  js  c++  java
  • 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 " % (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
    " % (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

  • 相关阅读:
    Netty相关知识积累
    Java内存管理
    使用nginx-upload-module搭建文件上传服务器
    mysql 5.7自动安装脚本
    CDH5集群搭建
    Linux常用命令
    编译原理要点四
    编译原理要点三
    编译原理要点二:
    编译原理要点
  • 原文地址:https://www.cnblogs.com/Xjng/p/3682567.html
Copyright © 2011-2022 走看看