这里是文章模块栏目内容页
python-daemon:使用Python编写后台进程

python-daemon是一个Python的第三方库。

其核心功能是创建一个Daemon进程(后台运行以及脱离当前父进程管控)

本文中,我们将会基于如上两个场景进行分析。

安装

python-daemon可以直接使用pip命令进行安装,安装方式如下:

pip install python-daemon

场景1:程序后台运行

很多时候,我们希望我们的程序能够后台执行。 
此时,一些常用的方法是nohup .... &,这类方法其实并不优雅。 
下面,我们来讲解如何使用python-daemon模块来编写一个原生后台执行的服务。

编写daemon2.py文件如下:

 #-*- coding: UTF-8 -*-
import time
import logging
import logging.handlers
from daemon import runner
class App(object):
    """
    # 定义一个应用
    """
    def __init__(self):
        """
        # 设置标准输入,标准输出,pid文件等
        """
        self.stdin_path = '/dev/null'
        self.stdout_path = '/dev/tty'
        self.stderr_path = '/dev/tty'
        self.pidfile_path =  '/tmp/foo.pid'
        self.pidfile_timeout = 5
    def run(self):
        """
        # 应用启动入口函数
        """
        # 设置日志打印规则
        logs = logging.getLogger('MyLogger')
        logs.setLevel(logging.DEBUG)
        fh = logging.handlers.RotatingFileHandler(
            '/tmp/test.log',maxBytes=10000000,backupCount=5)
        fh.setLevel(logging.DEBUG)
        formatter = logging.Formatter(u'%(asctime)s [%(levelname)s] %(message)s')
        fh.setFormatter(formatter)
        logs.addHandler(fh)  
        # 主程序
        while True:
            for i in range(10):
                logs.info("Beginning Scan {0}! \n".format(i))
            time.sleep(1)
# 整个程序的入口
app = App()
daemon_runner = runner.DaemonRunner(app)
daemon_runner.do_action()

该程序的启动方式如下:

usage: daemon2.py start|stop|restart

因此,可以通过该程序直接进行启动、停止、重启等操作。

场景2:程序脱离当前父进程管控

除了程序后台运行外,有时我们在一个应用中可以会从主进程fork出多个子进程。 
此时,一旦主进程发生重启等操作,所有的子进程均会受到影响导致退出。因此,如果我们希望子进程不受到主进程影响的话,需要让fork出的子进程脱离父进程管控,从而当父进程退出后,子进程不受影响。

demo示例如下:

 # -*- coding: UTF-8 -*-
import os
import time
import daemon
from logzero import logger
# 首先进行一次fork,防止对原有进程产生干扰
pid = os.fork()
if pid == 0:
    # 对于fork出的子进程,进入Daemon模式
    with daemon.DaemonContext():
        try:
            import setproctitle
            setproctitle.setproctitle("[TaskDaemon:1]")
        except ImportError as e:
            logger.warning("setproctitle module not found")
        time.sleep(3600)
else:
    # 对于父进程(原始进程),保留原有逻辑执行
    return 0


上一篇:Typetalk聊天API的python接口包

下一篇:没有了