如何在Python中创建一个守护进程?

时间:2021-01-20 23:22:30

Searching on Google reveals x2 code snippets. The first result is to this code recipe which has a lot of documentation and explanation, along with some useful discussion underneath.

搜索谷歌会显示x2代码片段。第一个结果是这个代码配方,它包含了大量的文档和说明,以及下面一些有用的讨论。

However, another code sample, whilst not containing so much documentation, includes sample code for passing commands such as start, stop and restart. It also creates a PID file which can be handy for checking if the daemon is already running etc.

然而,另一个代码示例,虽然没有包含这么多的文档,但包括了用于传递命令的示例代码,比如start、stop和restart。它还创建一个PID文件,可以方便地检查守护进程是否已经在运行等等。

These samples both explain how to create the daemon. Are there any additional things that need to be considered? Is one sample better than the other, and why?

这些示例都解释了如何创建守护进程。还有其他需要考虑的事情吗?一个样本比另一个更好吗?为什么?

15 个解决方案

#1


134  

Current solution

当前的解决方案

A reference implementation of PEP 3143 (Standard daemon process library) is now available as python-daemon.

PEP 3143(标准守护进程库)的参考实现现在可以作为python-守护进程使用。

Historical answer

历史的答案

Sander Marechal's code sample is superior to the original, which was originally posted in 2004. I once contributed a daemonizer for Pyro, but would probably use Sander's code if I had to do it over.

Sander Marechal的代码示例优于2004年发布的原始代码。我曾经为Pyro提供了一个daemonizer,但是如果我必须完成它,很可能会使用Sander的代码。

#2


152  

There are many fiddly things to take care of when becoming a well-behaved daemon process:

当成为一个行为良好的守护进程时,有许多棘手的事情需要处理:

  • prevent core dumps (many daemons run as root, and core dumps can contain sensitive information)

    防止核心转储(许多守护进程作为根运行,而核心转储可以包含敏感信息)

  • behave correctly inside a chroot gaol

    在chroot gaol中正确地操作。

  • set UID, GID, working directory, umask, and other process parameters appropriately for the use case

    适当地为用例设置UID、GID、工作目录、umask和其他过程参数。

  • relinquish elevated suid, sgid privileges

    放弃被提升的suid, sgid特权

  • close all open file descriptors, with exclusions depending on the use case

    关闭所有打开的文件描述符,并根据用例排除

  • behave correctly if started inside an already-detached context, such as init, inetd, etc.

    如果在已经分离的上下文(如init、inetd等)中启动,则应正确执行。

  • set up signal handlers for sensible daemon behaviour, but also with specific handlers determined by the use case

    为敏感的守护进程行为设置信号处理程序,但也使用由用例确定的特定处理程序

  • redirect the standard streams stdin, stdout, stderr since a daemon process no longer has a controlling terminal

    由于守护进程不再具有控制终端,因此重定向标准流stdin、stdout、stderr。

  • handle a PID file as a cooperative advisory lock, which is a whole can of worms in itself with many contradictory but valid ways to behave

    将PID文件作为合作的咨询锁来处理,这本身就是一堆蠕虫,它们有许多相互矛盾但有效的行为方式

  • allow proper cleanup when the process is terminated

    在进程终止时允许适当的清理

  • actually become a daemon process without leading to zombies

    实际上成为一个守护进程而不会导致僵尸

Some of these are standard, as described in canonical Unix literature (Advanced Programming in the UNIX Environment, by the late W. Richard Stevens, Addison-Wesley, 1992). Others, such as stream redirection and PID file handling, are conventional behaviour most daemon users would expect but that are less standardised.

其中一些是标准的,如规范Unix文献中所描述的(Unix环境中的高级编程,作者是W. Richard Stevens, Addison-Wesley, 1992)。其他的,如流重定向和PID文件处理,是大多数守护进程用户期望的常规行为,但不那么标准化。

All of these are covered by the PEP 3143 “Standard daemon process library” specification. The python-daemon reference implementation works on Python 2.7 or later, and Python 3.2 or later.

所有这些都包含在PEP 3143“标准守护进程库”规范中。Python -daemon引用实现在Python 2.7或更高版本上运行,Python 3.2或更高版本。

#3


88  

Here's my basic 'Howdy World' Python daemon that I start with, when I'm developing a new daemon application.

下面是我在开发一个新的守护进程应用程序时开始使用的基本的“Howdy World”Python守护进程。

#!/usr/bin/python
import time
from daemon import runner

class App():
    def __init__(self):
        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):
        while True:
            print("Howdy!  Gig'em!  Whoop!")
            time.sleep(10)

app = App()
daemon_runner = runner.DaemonRunner(app)
daemon_runner.do_action()

Note that you'll need the python-daemon library. You can install it by:

注意,您将需要python-daemon库。你可以通过以下方式安装:

pip install python-daemon

Then just start it with ./howdy.py start, and stop it with ./howdy.py stop.

那就从。/你好。py开始,然后停止。/你好。py停止。

#4


42  

Note the python-daemon package which solves a lot of problems behind daemons out of the box.

请注意python-daemon包,它解决了机器后台的许多问题。

Among other features it enables to (from Debian package description):

它支持的其他特性(来自Debian软件包描述):

  • Detach the process into its own process group.
  • 将流程分离到自己的流程组中。
  • Set process environment appropriate for running inside a chroot.
  • 设置流程环境,适合在chroot中运行。
  • Renounce suid and sgid privileges.
  • 放弃suid和sgid特权。
  • Close all open file descriptors.
  • 关闭所有打开的文件描述符。
  • Change the working directory, uid, gid, and umask.
  • 更改工作目录、uid、gid和umask。
  • Set appropriate signal handlers.
  • 设置适当的信号处理程序。
  • Open new file descriptors for stdin, stdout, and stderr.
  • 为stdin、stdout和stderr打开新的文件描述符。
  • Manage a specified PID lock file.
  • 管理指定的PID锁定文件。
  • Register cleanup functions for at-exit processing.
  • 为at-exit处理注册清理函数。

#5


24  

An alternative -- create a normal, non-daemonized Python program then externally daemonize it using supervisord. This can save a lot of headaches, and is *nix- and language-portable.

另一种选择——创建一个正常的、非恶魔化的Python程序,然后在外部使用monitor sord将其妖魔化。这样可以省去很多麻烦,而且可以移植语言和nix。

#6


12  

Probably not a direct answer to the question, but systemd can be used to run your application as a daemon. Here is an example:

也许不能直接回答这个问题,但是systemd可以作为守护进程运行应用程序。这是一个例子:

[Unit]
Description=Python daemon
After=syslog.target
After=network.target

[Service]
Type=simple
User=<run as user>
Group=<run as group group>
ExecStart=/usr/bin/python <python script home>/script.py

# Give the script some time to startup
TimeoutSec=300

[Install]
WantedBy=multi-user.target

I prefer this method because a lot of the work is done for you, and then your daemon script behaves similarly to the rest of your system.

我更喜欢这个方法,因为很多工作都是为您完成的,然后您的守护进程脚本的行为与系统的其他部分类似。

-Orby

#7


6  

YapDi is a relatively new python module that popped up in Hacker News. Looks pretty useful, can be used to convert a python script into daemon mode from inside the script.

YapDi是一个相对较新的python模块,出现在Hacker News中。看起来非常有用,可以用于将python脚本从脚本内部转换为守护进程模式。

#8


5  

since python-daemon has not yet supported python 3.x, and from what can be read on the mailing list, it may never will, i have written a new implementation of PEP 3143: pep3143daemon

因为python-daemon还不支持python 3。从邮件列表中可以读取的内容,可能永远也不会,我已经编写了一个新的PEP 3143: pep3143daemon的实现。

pep3143daemon should support at least python 2.6, 2.7 and 3.x

pep3143daemon至少应该支持python 2.6、2.7和3.x

It also contains a PidFile class.

它还包含一个PidFile类。

The library only depends on the standard library and on the six module.

该库仅依赖于标准库和六个模块。

It can be used as a drop in replacement for python-daemon.

它可以作为python-daemon的替代品。

Here is the documentation.

这是文档。

#9


3  

I am afraid the daemon module mentioned by @Dustin didn't work for me. Instead I installed python-daemon and used the following code:

@Dustin提到的守护进程模块恐怕对我不起作用。相反,我安装了python-daemon,并使用以下代码:

# filename myDaemon.py
import sys
import daemon
sys.path.append('/home/ubuntu/samplemodule') # till __init__.py
from samplemodule import moduleclass 

with daemon.DaemonContext():
    moduleclass.do_running() # I have do_running() function and whatever I was doing in __main__() in module.py I copied in it.

Running is easy

跑步是很容易的

> python myDaemon.py

just for completeness here is samplemodule directory content

为了完整起见,这里是samplemodule目录内容

>ls samplemodule
__init__.py __init__.pyc moduleclass.py

The content of moduleclass.py can be

moduleclass的内容。py可以

class moduleclass():
    ...

def do_running():
    m = moduleclass()
    # do whatever daemon is required to do.

#10


3  

This function will transform an application to a daemon:

该函数将应用程序转换为守护进程:

import sys
import os

def daemonize():
    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())

#11


2  

One more to thing to think about when daemonizing in python:

还有一件事要考虑,当你在python里自高自大的时候:

If your are using python logging and you want to continue using it after daemonizing, make sure to call close() on the handlers (particularly the file handlers).

如果您正在使用python日志记录,并且希望在守护之后继续使用它,请确保在处理程序(特别是文件处理程序)上调用close()。

If you don't do this the handler can still think it has files open, and your messages will simply disappear - in other words make sure the logger knows its files are closed!

如果您不这样做,处理程序仍然可以认为文件已经打开,您的消息将会消失——换句话说,确保日志记录器知道它的文件已经关闭!

This assumes when you daemonise you are closing ALL the open file descriptors indiscriminatingly - instead you could try closing all but the log files (but it's usually simpler to close all then reopen the ones you want).

这假定当您对所有打开的文件描述符进行隔离时,您将不加区分地关闭它们——相反,您可以尝试关闭除日志文件之外的所有文件(但是关闭所有文件然后重新打开所需的文件通常更简单)。

#12


1  

I modified a few lines in Sander Marechal's code sample (mentioned by @JeffBauer in the accepted answer) to add a quit() method that gets executed before the daemon is stopped. This is sometimes very useful.

我在Sander Marechal的代码示例中修改了一些行(在被接受的答案中提到@JeffBauer),添加一个quit()方法,该方法在守护进程停止之前执行。这有时非常有用。

Here it is.

在这儿。

Note: I don't use the "python-daemon" module because the documentation is still missing (see also many other SO questions) and is rather obscure (how to start/stop properly a daemon from command line with this module?)

注意:我没有使用“python-daemon”模块,因为文档仍然缺失(请参阅许多其他SO问题),并且相当模糊(如何从命令行正确启动/停止使用此模块的守护程序?)

#13


-1  

After a few years and many attempts, now I realize that there is a better way than wanting to start, stop, restart a daemon directly from Python: use the OS tools instead!

经过几年的努力,现在我意识到有一种比直接从Python中启动、停止、重新启动守护进程更好的方法:使用OS工具!

In short, instead of doing python myapp start and python myapp stop, I do this to start the app:

简而言之,我不是做python myapp start和python myapp stop,而是做这个来启动app:

screen -S myapp python myapp.py    
CTRL+A, D to detach

or screen -dmS myapp python myapp.py to start and detach it in one command.

或者是屏幕-dmS myapp mypython应用。在一个命令中启动和分离它。

Then:

然后:

screen -r myapp

to attach to this terminal again. Once in the terminal, it's possible to use CTRL+C to stop it.

再次连接到这个终端。一旦进入终端,就可以使用CTRL+C来停止它。

#14


-2  

The easiest way to create daemon with Python is to use the Twisted event-driven framework. It handles all of the stuff necessary for daemonization for you. It uses the Reactor Pattern to handle concurrent requests.

使用Python创建守护程序的最简单方法是使用Twisted事件驱动框架。它为您处理所有必需的守护进程。它使用反应器模式来处理并发请求。

#15


-23  

80% of the time, when folks say "daemon", they only want a server. Since the question is perfectly unclear on this point, it's hard to say what the possible domain of answers could be. Since a server is adequate, start there. If an actual "daemon" is actually needed (this is rare), read up on nohup as a way to daemonize a server.

80%的时候,当人们说“守护进程”时,他们只想要一个服务器。由于这个问题在这一点上完全不明确,很难说可能的答案范围是什么。既然服务器已经足够了,就从这里开始。如果实际需要一个“守护进程”(这很少见),请阅读nohup,将其作为守护服务器的一种方式。

Until such time as an actual daemon is actually required, just write a simple server.

在实际需要一个实际的守护进程之前,只需编写一个简单的服务器。

Also look at the WSGI reference implementation.

还可以查看WSGI参考实现。

Also look at the Simple HTTP Server.

还可以查看简单的HTTP服务器。

"Are there any additional things that need to be considered? " Yes. About a million things. What protocol? How many requests? How long to service each request? How frequently will they arrive? Will you use a dedicated process? Threads? Subprocesses? Writing a daemon is a big job.

“还有其他需要考虑的事情吗?”“是的。关于一百万年的事情。什么协议?要求多少?每个请求要服务多久?他们多久来一次?您会使用专用流程吗?线程?子流程?编写守护进程是一项重要的工作。

#1


134  

Current solution

当前的解决方案

A reference implementation of PEP 3143 (Standard daemon process library) is now available as python-daemon.

PEP 3143(标准守护进程库)的参考实现现在可以作为python-守护进程使用。

Historical answer

历史的答案

Sander Marechal's code sample is superior to the original, which was originally posted in 2004. I once contributed a daemonizer for Pyro, but would probably use Sander's code if I had to do it over.

Sander Marechal的代码示例优于2004年发布的原始代码。我曾经为Pyro提供了一个daemonizer,但是如果我必须完成它,很可能会使用Sander的代码。

#2


152  

There are many fiddly things to take care of when becoming a well-behaved daemon process:

当成为一个行为良好的守护进程时,有许多棘手的事情需要处理:

  • prevent core dumps (many daemons run as root, and core dumps can contain sensitive information)

    防止核心转储(许多守护进程作为根运行,而核心转储可以包含敏感信息)

  • behave correctly inside a chroot gaol

    在chroot gaol中正确地操作。

  • set UID, GID, working directory, umask, and other process parameters appropriately for the use case

    适当地为用例设置UID、GID、工作目录、umask和其他过程参数。

  • relinquish elevated suid, sgid privileges

    放弃被提升的suid, sgid特权

  • close all open file descriptors, with exclusions depending on the use case

    关闭所有打开的文件描述符,并根据用例排除

  • behave correctly if started inside an already-detached context, such as init, inetd, etc.

    如果在已经分离的上下文(如init、inetd等)中启动,则应正确执行。

  • set up signal handlers for sensible daemon behaviour, but also with specific handlers determined by the use case

    为敏感的守护进程行为设置信号处理程序,但也使用由用例确定的特定处理程序

  • redirect the standard streams stdin, stdout, stderr since a daemon process no longer has a controlling terminal

    由于守护进程不再具有控制终端,因此重定向标准流stdin、stdout、stderr。

  • handle a PID file as a cooperative advisory lock, which is a whole can of worms in itself with many contradictory but valid ways to behave

    将PID文件作为合作的咨询锁来处理,这本身就是一堆蠕虫,它们有许多相互矛盾但有效的行为方式

  • allow proper cleanup when the process is terminated

    在进程终止时允许适当的清理

  • actually become a daemon process without leading to zombies

    实际上成为一个守护进程而不会导致僵尸

Some of these are standard, as described in canonical Unix literature (Advanced Programming in the UNIX Environment, by the late W. Richard Stevens, Addison-Wesley, 1992). Others, such as stream redirection and PID file handling, are conventional behaviour most daemon users would expect but that are less standardised.

其中一些是标准的,如规范Unix文献中所描述的(Unix环境中的高级编程,作者是W. Richard Stevens, Addison-Wesley, 1992)。其他的,如流重定向和PID文件处理,是大多数守护进程用户期望的常规行为,但不那么标准化。

All of these are covered by the PEP 3143 “Standard daemon process library” specification. The python-daemon reference implementation works on Python 2.7 or later, and Python 3.2 or later.

所有这些都包含在PEP 3143“标准守护进程库”规范中。Python -daemon引用实现在Python 2.7或更高版本上运行,Python 3.2或更高版本。

#3


88  

Here's my basic 'Howdy World' Python daemon that I start with, when I'm developing a new daemon application.

下面是我在开发一个新的守护进程应用程序时开始使用的基本的“Howdy World”Python守护进程。

#!/usr/bin/python
import time
from daemon import runner

class App():
    def __init__(self):
        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):
        while True:
            print("Howdy!  Gig'em!  Whoop!")
            time.sleep(10)

app = App()
daemon_runner = runner.DaemonRunner(app)
daemon_runner.do_action()

Note that you'll need the python-daemon library. You can install it by:

注意,您将需要python-daemon库。你可以通过以下方式安装:

pip install python-daemon

Then just start it with ./howdy.py start, and stop it with ./howdy.py stop.

那就从。/你好。py开始,然后停止。/你好。py停止。

#4


42  

Note the python-daemon package which solves a lot of problems behind daemons out of the box.

请注意python-daemon包,它解决了机器后台的许多问题。

Among other features it enables to (from Debian package description):

它支持的其他特性(来自Debian软件包描述):

  • Detach the process into its own process group.
  • 将流程分离到自己的流程组中。
  • Set process environment appropriate for running inside a chroot.
  • 设置流程环境,适合在chroot中运行。
  • Renounce suid and sgid privileges.
  • 放弃suid和sgid特权。
  • Close all open file descriptors.
  • 关闭所有打开的文件描述符。
  • Change the working directory, uid, gid, and umask.
  • 更改工作目录、uid、gid和umask。
  • Set appropriate signal handlers.
  • 设置适当的信号处理程序。
  • Open new file descriptors for stdin, stdout, and stderr.
  • 为stdin、stdout和stderr打开新的文件描述符。
  • Manage a specified PID lock file.
  • 管理指定的PID锁定文件。
  • Register cleanup functions for at-exit processing.
  • 为at-exit处理注册清理函数。

#5


24  

An alternative -- create a normal, non-daemonized Python program then externally daemonize it using supervisord. This can save a lot of headaches, and is *nix- and language-portable.

另一种选择——创建一个正常的、非恶魔化的Python程序,然后在外部使用monitor sord将其妖魔化。这样可以省去很多麻烦,而且可以移植语言和nix。

#6


12  

Probably not a direct answer to the question, but systemd can be used to run your application as a daemon. Here is an example:

也许不能直接回答这个问题,但是systemd可以作为守护进程运行应用程序。这是一个例子:

[Unit]
Description=Python daemon
After=syslog.target
After=network.target

[Service]
Type=simple
User=<run as user>
Group=<run as group group>
ExecStart=/usr/bin/python <python script home>/script.py

# Give the script some time to startup
TimeoutSec=300

[Install]
WantedBy=multi-user.target

I prefer this method because a lot of the work is done for you, and then your daemon script behaves similarly to the rest of your system.

我更喜欢这个方法,因为很多工作都是为您完成的,然后您的守护进程脚本的行为与系统的其他部分类似。

-Orby

#7


6  

YapDi is a relatively new python module that popped up in Hacker News. Looks pretty useful, can be used to convert a python script into daemon mode from inside the script.

YapDi是一个相对较新的python模块,出现在Hacker News中。看起来非常有用,可以用于将python脚本从脚本内部转换为守护进程模式。

#8


5  

since python-daemon has not yet supported python 3.x, and from what can be read on the mailing list, it may never will, i have written a new implementation of PEP 3143: pep3143daemon

因为python-daemon还不支持python 3。从邮件列表中可以读取的内容,可能永远也不会,我已经编写了一个新的PEP 3143: pep3143daemon的实现。

pep3143daemon should support at least python 2.6, 2.7 and 3.x

pep3143daemon至少应该支持python 2.6、2.7和3.x

It also contains a PidFile class.

它还包含一个PidFile类。

The library only depends on the standard library and on the six module.

该库仅依赖于标准库和六个模块。

It can be used as a drop in replacement for python-daemon.

它可以作为python-daemon的替代品。

Here is the documentation.

这是文档。

#9


3  

I am afraid the daemon module mentioned by @Dustin didn't work for me. Instead I installed python-daemon and used the following code:

@Dustin提到的守护进程模块恐怕对我不起作用。相反,我安装了python-daemon,并使用以下代码:

# filename myDaemon.py
import sys
import daemon
sys.path.append('/home/ubuntu/samplemodule') # till __init__.py
from samplemodule import moduleclass 

with daemon.DaemonContext():
    moduleclass.do_running() # I have do_running() function and whatever I was doing in __main__() in module.py I copied in it.

Running is easy

跑步是很容易的

> python myDaemon.py

just for completeness here is samplemodule directory content

为了完整起见,这里是samplemodule目录内容

>ls samplemodule
__init__.py __init__.pyc moduleclass.py

The content of moduleclass.py can be

moduleclass的内容。py可以

class moduleclass():
    ...

def do_running():
    m = moduleclass()
    # do whatever daemon is required to do.

#10


3  

This function will transform an application to a daemon:

该函数将应用程序转换为守护进程:

import sys
import os

def daemonize():
    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())

#11


2  

One more to thing to think about when daemonizing in python:

还有一件事要考虑,当你在python里自高自大的时候:

If your are using python logging and you want to continue using it after daemonizing, make sure to call close() on the handlers (particularly the file handlers).

如果您正在使用python日志记录,并且希望在守护之后继续使用它,请确保在处理程序(特别是文件处理程序)上调用close()。

If you don't do this the handler can still think it has files open, and your messages will simply disappear - in other words make sure the logger knows its files are closed!

如果您不这样做,处理程序仍然可以认为文件已经打开,您的消息将会消失——换句话说,确保日志记录器知道它的文件已经关闭!

This assumes when you daemonise you are closing ALL the open file descriptors indiscriminatingly - instead you could try closing all but the log files (but it's usually simpler to close all then reopen the ones you want).

这假定当您对所有打开的文件描述符进行隔离时,您将不加区分地关闭它们——相反,您可以尝试关闭除日志文件之外的所有文件(但是关闭所有文件然后重新打开所需的文件通常更简单)。

#12


1  

I modified a few lines in Sander Marechal's code sample (mentioned by @JeffBauer in the accepted answer) to add a quit() method that gets executed before the daemon is stopped. This is sometimes very useful.

我在Sander Marechal的代码示例中修改了一些行(在被接受的答案中提到@JeffBauer),添加一个quit()方法,该方法在守护进程停止之前执行。这有时非常有用。

Here it is.

在这儿。

Note: I don't use the "python-daemon" module because the documentation is still missing (see also many other SO questions) and is rather obscure (how to start/stop properly a daemon from command line with this module?)

注意:我没有使用“python-daemon”模块,因为文档仍然缺失(请参阅许多其他SO问题),并且相当模糊(如何从命令行正确启动/停止使用此模块的守护程序?)

#13


-1  

After a few years and many attempts, now I realize that there is a better way than wanting to start, stop, restart a daemon directly from Python: use the OS tools instead!

经过几年的努力,现在我意识到有一种比直接从Python中启动、停止、重新启动守护进程更好的方法:使用OS工具!

In short, instead of doing python myapp start and python myapp stop, I do this to start the app:

简而言之,我不是做python myapp start和python myapp stop,而是做这个来启动app:

screen -S myapp python myapp.py    
CTRL+A, D to detach

or screen -dmS myapp python myapp.py to start and detach it in one command.

或者是屏幕-dmS myapp mypython应用。在一个命令中启动和分离它。

Then:

然后:

screen -r myapp

to attach to this terminal again. Once in the terminal, it's possible to use CTRL+C to stop it.

再次连接到这个终端。一旦进入终端,就可以使用CTRL+C来停止它。

#14


-2  

The easiest way to create daemon with Python is to use the Twisted event-driven framework. It handles all of the stuff necessary for daemonization for you. It uses the Reactor Pattern to handle concurrent requests.

使用Python创建守护程序的最简单方法是使用Twisted事件驱动框架。它为您处理所有必需的守护进程。它使用反应器模式来处理并发请求。

#15


-23  

80% of the time, when folks say "daemon", they only want a server. Since the question is perfectly unclear on this point, it's hard to say what the possible domain of answers could be. Since a server is adequate, start there. If an actual "daemon" is actually needed (this is rare), read up on nohup as a way to daemonize a server.

80%的时候,当人们说“守护进程”时,他们只想要一个服务器。由于这个问题在这一点上完全不明确,很难说可能的答案范围是什么。既然服务器已经足够了,就从这里开始。如果实际需要一个“守护进程”(这很少见),请阅读nohup,将其作为守护服务器的一种方式。

Until such time as an actual daemon is actually required, just write a simple server.

在实际需要一个实际的守护进程之前,只需编写一个简单的服务器。

Also look at the WSGI reference implementation.

还可以查看WSGI参考实现。

Also look at the Simple HTTP Server.

还可以查看简单的HTTP服务器。

"Are there any additional things that need to be considered? " Yes. About a million things. What protocol? How many requests? How long to service each request? How frequently will they arrive? Will you use a dedicated process? Threads? Subprocesses? Writing a daemon is a big job.

“还有其他需要考虑的事情吗?”“是的。关于一百万年的事情。什么协议?要求多少?每个请求要服务多久?他们多久来一次?您会使用专用流程吗?线程?子流程?编写守护进程是一项重要的工作。