我目前正在尝试手动创建一个简单的守护进程,我不想使用现有的外部库来避免开销。
我目前正在检查我的进程何时运行,它尚未创建 PID 文件(意味着它正在运行),如本文所述。
我还有一个守护进程模块,用于从当前进程中分离 PID 并重定向 stdout 和 stderr(因此即使我结束会话,我的守护进程也会继续运行):
import os
import sys
def daemonize(stdin="/dev/null", stdout="/dev/null", stderr="/dev/null"):
try:
pid = os.fork()
if pid > 0:
sys.exit(0)
except OSError, e:
sys.stderr.write ("fork #1 failed: (%d) %s\n" % (e.errno, e.strerror) )
sys.exit(1)
os.chdir("/")
os.umask(0)
os.setsid()
try:
pid = os.fork()
if pid > 0:
sys.exit(0)
except OSError, e:
sys.stderr.write ("fork #2 failed: (%d) %s\n" % (e.errno, e.strerror) )
sys.exit(1)
stdin_par = os.path.dirname(stdin)
stdout_par = os.path.dirname(stdout)
stderr_par = os.path.dirname(stderr)
if not stdin_par:
os.path.makedirs(stdin_par)
if not stdout_par:
os.path.makedirs(stdout_par)
if not stderr_par:
os.path.makedirs(stderr_par)
si = open(stdin, 'r')
so = open(stdout, 'a+')
se = open(stderr, 'a+', 0)
os.dup2(si.fileno(), sys.stdin.fileno())
os.dup2(so.fileno(), sys.stdout.fileno())
os.dup2(se.fileno(), sys.stderr.fileno())
所以目前我可以像下面的示例行一样运行我的进程,它将正确运行我的守护进程:
>$ python myapp.py
但要停止它,我必须 grep PID(或从锁定文件中获取)并在以下操作后手动擦除 PID:
>$ ps -ef | grep myapp
xxxxx 11901 1 0 19:48 ? 00:00:00 python src/myapp.py
xxxxx 12282 7600 0 19:54 pts/7 00:00:00 grep myapp
>$ kill -9 11901
>$ rm -rf /path/to/lock.pid
我想要一个更像 Unix 的守护进程,我可以使用以下命令管理守护进程生命周期:
>$ python myapp.py start
>$ python myapp.py stop
>$ python myapp.py restart
我当然可以用这个argparse
模块来做,但这似乎有点乏味和丑陋。
你知道在 Python 中拥有一个 Unix 风格的守护进程的简单而优雅的解决方案吗?