【问题标题】:How to implement a daemon process in Python?如何在 Python 中实现守护进程?
【发布时间】:2016-03-16 10:19:37
【问题描述】:

我正在编写一个小程序,它有一个心跳进程和一个回显进程。我用一个多处理库实现了这个,但它似乎不起作用。

from multiprocessing import Process
import os
import time

def ticking():
    while True:
        time.sleep(1)
        print 'ticking'

def echo():
    while True:
        a = raw_input('please type something')
        print 'echo: ' + a

if __name__ == '__main__':
    p = Process(target=ticking, args=())
    p.start()
    p.join()

    p = Process(target=echo, args=())
    p.start()
    p.join()

【问题讨论】:

  • python-daemon 库是一个方便的包,可以轻松创建守护进程。
  • 同意,multiprocessing 不是实现守护进程的正确工具。通常,您希望对 Unix 守护程序使用双分叉惯用语,因此只需使用 Carpetsmoker 链接的库即可。
  • @Carpetsmoker 谢谢,会试试 :)

标签: python multiprocessing daemon


【解决方案1】:

您创建了一个将永远运行的进程并将join() 用于它。第二个进程永远不会被创建,因为join() 将永远停止你的主进程。

如果这是您想要继续的方式,那么您应该首先创建两个进程,然后加入它们:

if __name__ == '__main__':
    p1 = Process(target=ticking, args=())
    p1.start()

    p2 = Process(target=echo, args=())
    p2.start()

    p1.join()
    p2.join()

【讨论】:

  • join() 的文档。 “该方法一直阻塞,直到调用 join() 方法的进程终止。”
  • 是的,但结果是一样的:P
【解决方案2】:

要创建一个守护进程,你可以使用这个函数:

def daemonize():
    """UNIX double fork mechanism."""
    try:
        pid = os.fork()
        if pid > 0:
            # exit first parent
            sys.exit(0)
    except OSError as err:
        sys.stderr.write('_Fork #1 failed: {0}\n'.format(err))
        sys.exit(1)
    # decouple from parent environment
    os.chdir('/')
    os.setsid()
    os.umask(0)
    # do second fork
    try:
        pid = os.fork()
        if pid > 0:
            # exit from second parent
            sys.exit(0)
    except OSError as err:
        sys.stderr.write('_Fork #2 failed: {0}\n'.format(err))
        sys.exit(1)
    # redirect standard file descriptors
    sys.stdout.flush()
    sys.stderr.flush()
    si = open(os.devnull, 'r')
    so = open(os.devnull, 'w')
    se = open(os.devnull, 'w')
    os.dup2(si.fileno(), sys.stdin.fileno())
    os.dup2(so.fileno(), sys.stdout.fileno())
    os.dup2(se.fileno(), sys.stderr.fileno())

【讨论】:

  • 在阅读了this 之后,我不明白为什么要这样做os.setsid()。但是为什么要做 (1) os.chdir('/') (2) os.umask(0)(3) 那些文件描述符呢?如果我不做其中的一些怎么办?我们也可以用 python multiprocessing.Process 做类似的事情吗?
  • @Mahesha999 1. 我们需要更改工作目录以确保安全。例如,将来运行应用程序的目录可能会被卸载。根目录是最好的方法。 2. umask(0) 提供对将由守护程序创建的文件的完全访问权限 (-rw-rw-rw-)。 3. 当守护进程与终端断开连接时,我们关闭文件描述符,并且不应该通过管道发送任何数据。为此,我们打开 /dev/null 并将守护程序的文件描述符更改为 /dev/null 描述符。
  • @Mahesha999 我们做了所有这些事情,因为这些都是创建守护进程的规则:netzmafia.de/skripten/unix/linux-daemon-howto.html 我展示了如何通过一个函数将应用程序转换为守护进程的方法。此方法仅依赖于 sys 和 os 模块。还有其他在python中创建unix守护进程的方法,它只是其中之一。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-11
  • 2012-08-10
  • 2016-01-14
  • 1970-01-01
  • 2013-02-28
相关资源
最近更新 更多