文档章节

3.x 在Unix系统上面启动守护进程

d
 dragon_tech
发布于 01/21 14:02
字数 608
阅读 7
收藏 1

12.14 在Unix系统上面启动守护进程

问题

你想编写一个作为一个在Unix或类Unix系统上面运行的守护进程运行的程序。

解决方案

创建一个正确的守护进程需要一个精确的系统调用序列以及对于细节的控制。 下面的代码展示了怎样定义一个守护进程,可以启动后很容易的停止它。

#!/usr/bin/env python3
# daemon.py

import os
import sys

import atexit
import signal

def daemonize(pidfile, *, stdin='/dev/null',
                          stdout='/dev/null',
                          stderr='/dev/null'):

    if os.path.exists(pidfile):
        raise RuntimeError('Already running')

    # First fork (detaches from parent)
    try:
        if os.fork() > 0:
            raise SystemExit(0)   # Parent exit
    except OSError as e:
        raise RuntimeError('fork #1 failed.')

    os.chdir('/')
    os.umask(0)
    os.setsid()
    # Second fork (relinquish session leadership)
    try:
        if os.fork() > 0:
            raise SystemExit(0)
    except OSError as e:
        raise RuntimeError('fork #2 failed.')

    # Flush I/O buffers
    sys.stdout.flush()
    sys.stderr.flush()

    # Replace file descriptors for stdin, stdout, and stderr
    with open(stdin, 'rb', 0) as f:
        os.dup2(f.fileno(), sys.stdin.fileno())
    with open(stdout, 'ab', 0) as f:
        os.dup2(f.fileno(), sys.stdout.fileno())
    with open(stderr, 'ab', 0) as f:
        os.dup2(f.fileno(), sys.stderr.fileno())

    # Write the PID file
    with open(pidfile,'w') as f:
        print(os.getpid(),file=f)

    # Arrange to have the PID file removed on exit/signal
    atexit.register(lambda: os.remove(pidfile))

    # Signal handler for termination (required)
    def sigterm_handler(signo, frame):
        raise SystemExit(1)

    signal.signal(signal.SIGTERM, sigterm_handler)

def main():
    import time
    sys.stdout.write('Daemon started with pid {}\n'.format(os.getpid()))
    while True:
        sys.stdout.write('Daemon Alive! {}\n'.format(time.ctime()))
        time.sleep(10)

if __name__ == '__main__':
    PIDFILE = '/tmp/daemon.pid'

    if len(sys.argv) != 2:
        print('Usage: {} [start|stop]'.format(sys.argv[0]), file=sys.stderr)
        raise SystemExit(1)

    if sys.argv[1] == 'start':
        try:
            daemonize(PIDFILE,
                      stdout='/tmp/daemon.log',
                      stderr='/tmp/dameon.log')
        except RuntimeError as e:
            print(e, file=sys.stderr)
            raise SystemExit(1)

        main()

    elif sys.argv[1] == 'stop':
        if os.path.exists(PIDFILE):
            with open(PIDFILE) as f:
                os.kill(int(f.read()), signal.SIGTERM)
        else:
            print('Not running', file=sys.stderr)
            raise SystemExit(1)

    else:
        print('Unknown command {!r}'.format(sys.argv[1]), file=sys.stderr)
        raise SystemExit(1)

要启动这个守护进程,用户需要使用如下的命令:

bash % daemon.py start
bash % cat /tmp/daemon.pid
2882
bash % tail -f /tmp/daemon.log
Daemon started with pid 2882
Daemon Alive! Fri Oct 12 13:45:37 2012
Daemon Alive! Fri Oct 12 13:45:47 2012
...

守护进程可以完全在后台运行,因此这个命令会立即返回。 不过,你可以像上面那样查看与它相关的pid文件和日志。要停止这个守护进程,使用:

bash % daemon.py stop
bash %

本文转载自:https://python3-cookbook.readthedocs.io/zh_CN/latest/c12/p14_launching_daemon_process_on_unix.html

共有 人打赏支持
上一篇: 密码忘记的
d
粉丝 2
博文 231
码字总数 5810
作品 0
西安
私信 提问
linux各项系统服务的功能

Linux服务器在启动时需要启动很多系统服务,它们向本地和网络用户提供了Linux的系统功能接口,直接面向应用程序和用户。提供这些服务的程序是由运行在后台的守护进程(daemons) 来执行的。守...

fighting-cluber
2014/03/28
825
0
深入理解Linux操作系统守护进程的意义

Linux服务器在启动时需要启动很多系统服务,它们向本地和网络用户提供了Linux的系统功能接口,直接面向应用程序和用户。提供这些服务的程序是由运行在后台的守护进程(daemons)来执行的。守...

JavaGG
2009/05/07
670
0
linux常见服务器端口

linux 常见服务端口 2008-01-21 16:24:52 分类: LINUX 转 Linux服务器在启动时需要启动很多系统服务,它们向本地和网络用户提供了Linux的系统功能接口,直接面向应用程序和用户。提供这些服...

小孩66
2015/08/11
52
0
浅谈linux性能调优之七:裁剪系统服务

通常部署应用服务,对单台服务器而言只提供单一服务,甚至利用集群技术,分布式技术多台服务器来提供高可用,高性能的服务。这样对于大多系统提供多种服务 的现状显然不符,这就要求我们管理...

我爱吃葱花
2014/08/11
0
0
浅谈linux性能调优之七:裁剪系统服务

通常部署应用服务,对单台服务器而言只提供单一服务,甚至利用集群技术,分布式技术多台服务器来提供高可用,高性能的服务。这样对于大多系统提供多种服务 的现状显然不符,这就要求我们管理...

OscerSong
2013/07/13
0
0

没有更多内容

加载失败,请刷新页面

加载更多

RabbitMQ入门

RabbitMQ是一个由erlang开发的基于AMQP(Advanced Message Queue)协议的开源实现。用于在分布式系统中存储转发消息,在易用性、扩展性、高可用性等方面都非常的优秀。是当前最主流的消息中间...

watermelon11
今天
15
0
今天的学习

自动加载:方法一 function __autoload( $className ){在这里,完成加载B这个类文件的工作。}class A{} //这是一个类$a1 = new A(); //这里没有自动加载的发生,因为A这个类...

墨冥
今天
2
0
印刷工艺步骤

印刷厂从收到订单到交付整个流程,一般涉及到以下步骤 1.设计(经过软件如cdr,psd,ai等等设计需要印刷的名片,宣传单,画册等物料); 2.排版拼版(在电脑软件这区域完成); 3.出版、出硫...

focusone
昨天
4
0
virtualbox中安装ubuntu

virtualbox+ubuntu 安装virtualbox,当前版本是6.0.4 下载ubuntu安装盘,建议lubuntu,链接是http://mirrors.ustc.edu.cn/ubuntu-cdimage/lubuntu/releases/18.04.2/release/lubuntu-18.04.......

chuqq
昨天
5
0
exists 谓词的子查询

https://blog.csdn.net/qq_19782019/article/details/78730882

仟昭
昨天
6
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部