高效的Python守护进程

36 投票
3 回答
60002 浏览
提问于 2025-04-16 09:38

我很好奇怎么能在后台运行一个Python脚本,让它每60秒重复执行一个任务。我知道可以用&符号把某个东西放到后台,这样做在这种情况下有效吗?

我在想用一个循环,让它等60秒再重新执行,但感觉这样做有点不太对劲。

3 个回答

8

在命令行中使用 & 是最简单的方法,就像 Greg 说的那样。

不过,如果你想创建一个功能强大的后台程序(Daemon),你就需要了解一下 os.fork() 这个命令。

这里有个来自 维基百科 的例子:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import os, time

def createDaemon():
  """ 
      This function create a service/Daemon that will execute a det. task
  """

  try:
    # Store the Fork PID
    pid = os.fork()

    if pid > 0:
      print 'PID: %d' % pid
      os._exit(0)

  except OSError, error:
    print 'Unable to fork. Error: %d (%s)' % (error.errno, error.strerror)
    os._exit(1)

  doTask()

def doTask():
  """ 
      This function create a task that will be a daemon
  """

  # Open the file in write mode
  file = open('/tmp/tarefa.log', 'w')

  # Start the write
  while True:
    print >> file, time.ctime()
    file.flush()
    time.sleep(2)

  # Close the file
  file.close()

if __name__ == '__main__':

  # Create the Daemon
  createDaemon()

然后你可以把需要执行的任务放在 doTask() 这个块里面。

这样你就不需要用 & 来启动它了,而且可以让你进一步自定义执行的方式。

110

与其自己写一个守护进程,不如使用python-daemon!这个库遵循了PEP 3143的标准守护进程规范,也就是“标准守护进程库”。

我提供了一个示例代码,基于这个问题的接受答案。虽然代码看起来几乎一模一样,但它有一个重要的根本区别。如果没有python-daemon,你需要使用&把你的进程放到后台,还要用nohup来防止在退出终端时进程被杀掉。而使用这个库时,程序运行时会自动与终端分离。

例如:

import daemon
import time

def do_something():
    while True:
        with open("/tmp/current_time.txt", "w") as f:
            f.write("The time is now " + time.ctime())
        time.sleep(5)

def run():
    with daemon.DaemonContext():
        do_something()

if __name__ == "__main__":
    run()

要实际运行它:

python background_test.py

注意这里没有&

另外,这个StackOverflow的其他回答详细解释了使用python-daemon的许多好处。

16

我觉得你的想法基本上就是你想要的。举个例子:

import time

def do_something():
    with open("/tmp/current_time.txt", "w") as f:
        f.write("The time is now " + time.ctime())

def run():
    while True:
        time.sleep(60)
        do_something()

if __name__ == "__main__":
    run()

调用 time.sleep(60) 这个命令会让你的程序暂停60秒。当时间到了,操作系统会把你的程序唤醒,然后运行 do_something() 这个函数,之后再把它放回休眠状态。在程序休眠的时候,它什么都不做,这样非常高效。这是一种编写后台服务的常见方式。

如果你想从命令行运行这个程序,可以使用 &:

$ python background_test.py &

这样做的时候,脚本的任何输出都会显示在你启动它的那个终端上。你可以通过重定向输出,来避免这种情况:

$ python background_test.py >stdout.txt 2>stderr.txt &

撰写回答