python 守护进程

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python 守护进程相关的知识,希望对你有一定的参考价值。

参考技术A 一、守护进程的特性

守护进程是一个在后台运行并且不受任何终端控制的进程(守护进程独立于所有终端,之所以脱离于终端是为了避免进程被任何终端所产生的信息所打断,其在执行过程中的信息也不在任何终端上显示。)

二、守护进程的作用

守护进程是一类在后台执行,生命周期较长的进程,它一般随系统启动运行,在系统关闭的时候停止。所以守护进程一般用作系统后台服务。

三、如何编写一个守护进程

编写守护进程实际上是把一个普通进程按照守护进程的特性进行改造。

守护进程的开发涉及到子进程、进程组、会晤期、信号量、文件权限、目录和控制终端等多个概念。

由于守护进程是脱离控制终端的,因此首先创建子进程,终止父进程,使得程序在shell终端里造成一个已经运行完毕的假象。之后所有的工作都在子进程中完成,而用户在shell终端里则可以执行其他的命令,从而使得程序以僵尸进程形式运行,在形式上做到了与控制终端的脱离。

四、python 编写守护进程

参考: https://cloud.tencent.com/developer/article/1411989

python 守护进程(daemon)

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import sys, os

‘‘‘将当前进程fork为一个守护进程
   注意:如果你的守护进程是由inetd启动的,不要这样做!inetd完成了
   所有需要做的事情,包括重定向标准文件描述符,需要做的事情只有chdir()和umask()了
‘‘‘

def daemon(stdin=‘/dev/null‘, stdout=‘/dev/null‘, stderr=‘/dev/null‘):
    # 重定向标准文件描述符(默认情况下定向到/dev/null)  
    try:
        pid = os.fork()
        # 父进程(会话组头领进程)退出,这意味着一个非会话组头领进程永远不能重新获得控制终端。  
        if pid > 0:
            sys.exit(0)  # 父进程退出  
    except OSError, e:
        sys.stderr.write("fork #1 failed: (%d) %s\n" % (e.errno, e.strerror))
        sys.exit(1)

        # 从母体环境脱离  
    os.chdir("/")  # chdir确认进程不保持任何目录于使用状态,否则不能umount一个文件系统。也可以改变到对于守护程序运行重要的文件所在目录  
    os.umask(0)  # 调用umask(0)以便拥有对于写的任何东西的完全控制,因为有时不知道继承了什么样的umask。  
    os.setsid()  # setsid调用成功后,进程成为新的会话组长和新的进程组长,并与原来的登录会话和进程组脱离。  

    # 执行第二次fork  
    try:
        pid = os.fork()
        if pid > 0:
            sys.exit(0)  # 第二个父进程退出  
    except OSError, e:
        sys.stderr.write("fork #2 failed: (%d) %s\n" % (e.errno, e.strerror))
        sys.exit(1)

        # 进程已经是守护进程了,重定向标准文件描述符  

    for f in sys.stdout, sys.stderr: f.flush()
    si = open(stdin, ‘r‘)
    so = open(stdout, ‘a+‘)
    se = open(stderr, ‘a+‘)
    os.dup2(si.fileno(), sys.stdin.fileno())  # dup2函数原子化关闭和复制文件描述符  
    os.dup2(so.fileno(), sys.stdout.fileno())
    os.dup2(se.fileno(), sys.stderr.fileno())


# 示例函数:每秒打印一个数字和时间戳  
def main():
    import time
    sys.stdout.write(‘Daemon started with pid %d\n‘ % os.getpid())
    sys.stdout.write(‘Daemon stdout output\n‘)
    sys.stderr.write(‘Daemon stderr output\n‘)
    c = 0
    while True:
        sys.stdout.write(‘%d: %s\n‘ % (c, time.ctime()))
        sys.stdout.flush()
        c = c + 1
        time.sleep(1)


if __name__ == "__main__":
    daemone(‘/dev/null‘, ‘/tmp/daemon_stdout.log‘, ‘/tmp/daemon_error.log‘)
    main()

# 可以通过命令ps -ef | grep daemon.py查看后台运行的继承
# 在/tmp/daemon_error.log会记录错误运行日志
# 在/tmp/daemon_stdout.log会记录标准输出日志。


本文出自 “baby神” 博客,请务必保留此出处http://babyshen.blog.51cto.com/8405584/1888273

以上是关于python 守护进程的主要内容,如果未能解决你的问题,请参考以下文章

python下编写守护进程

041.Python守护进程,锁信号量和事件

python学习笔记——守护进程

python之守护进程

Python全栈之路模块----之-----守护进程进程锁队列生产者消费者模式

Python 进程池非守护进程?