CQP*_*CQP 29 python daemon python-daemon
如果这是一个新手问题,我是守护进程的新手.
在其他几个答案中(例如,这个问题),人们建议使用python-daemon包,因为它完全实现了PEP 3143标准.
不幸的是,python-daemon 在文档上有点亮(或者更有可能我对知识/经验有点轻视......;)),我想我可能遗漏了一些非常基本的东西.这是我正在做的事情:
我有以下内容:
import daemon
logfile = open('daemon.log', 'w')
context = daemon.DaemonContext(stdout = logfile, stderr = logfile)
context.open()
with context:
do_something_1()
do_something_2()
Run Code Online (Sandbox Code Playgroud)
问题:如何使用python-daemon设置守护进程,如何启动并停止它?
附注:
我基本上猜测这个.open()方法应该如何/是否应该在这里使用 - 文档在这一点上并不是很明确.无论我是否包括它,似乎都会发生同样的事情.
所以,现在我该怎么办?当我尝试运行此文件时,例如:
python startConsumerDaemons.py
Run Code Online (Sandbox Code Playgroud)
它似乎运行do_something_1(),但不是第二个.而且,它似乎离开程序连接到终端窗口.IE,stdout没有重定向,当我关闭终端窗口时,进程被终止.所以,我很确定我在这里做错了什么......我应该做些什么呢?
最后,一旦我让守护进程运行,我该如何停止/重启它(例如,如果我对底层代码进行了更改)?
phz*_*nki 11
这就是我拥有的,对我有用.它还有一个sysv init脚本.Repo在GitHub上,我还有一篇简短的博客文章,其中包含我发现的其他可能解决方案的链接.
只能运行一个守护程序进程:它由PID锁定文件管理,就像大多数其他Linux守护进程一样.要阻止它,做
kill `cat /var/run/eg_daemon.pid`
Run Code Online (Sandbox Code Playgroud)
要查看它是否正在运行:
ps -elf | grep `cat /var/run/eg_daemon.pid`
Run Code Online (Sandbox Code Playgroud)
使用pidfile子模块,自动管理PID文件.守护程序停止后,pidfile将被清除.请参阅链接的GitHub repo以获取init脚本.
这是Python守护程序代码:
#!/usr/bin/env python3.5
import sys
import os
import time
import argparse
import logging
import daemon
from daemon import pidfile
debug_p = False
def do_something(logf):
### This does the "work" of the daemon
logger = logging.getLogger('eg_daemon')
logger.setLevel(logging.INFO)
fh = logging.FileHandler(logf)
fh.setLevel(logging.INFO)
formatstr = '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
formatter = logging.Formatter(formatstr)
fh.setFormatter(formatter)
logger.addHandler(fh)
while True:
logger.debug("this is a DEBUG message")
logger.info("this is an INFO message")
logger.error("this is an ERROR message")
time.sleep(5)
def start_daemon(pidf, logf):
### This launches the daemon in its context
### XXX pidfile is a context
with daemon.DaemonContext(
working_directory='/var/lib/eg_daemon',
umask=0o002,
pidfile=pidfile.TimeoutPIDLockFile(pidf),
) as context:
do_something(logf)
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Example daemon in Python")
parser.add_argument('-p', '--pid-file', default='/var/run/eg_daemon.pid')
parser.add_argument('-l', '--log-file', default='/var/log/eg_daemon.log')
args = parser.parse_args()
start_daemon(pidf=args.pid_file, logf=args.log_file)
Run Code Online (Sandbox Code Playgroud)
为了完整起见,这是init脚本.请注意,"kill"实际上只是发送POSIX信号的方法 - 有关概述,请参阅信号(7)的手册页.python-daemon上下文将捕获信号,彻底终止进程关闭文件描述符,并自动删除PID文件.所以,这真的是一个干净的终止.
您可以编写代码来捕获SIGUSR1或类似的东西,以便重新加载守护程序配置.编写Python停止守护进程没有任何好处.
#!/bin/bash
#
# eg_daemon Startup script for eg_daemon
#
# chkconfig: - 87 12
# description: eg_daemon is a dummy Python-based daemon
# config: /etc/eg_daemon/eg_daemon.conf
# config: /etc/sysconfig/eg_daemon
# pidfile: /var/run/eg_daemon.pid
#
### BEGIN INIT INFO
# Provides: eg_daemon
# Required-Start: $local_fs
# Required-Stop: $local_fs
# Short-Description: start and stop eg_daemon server
# Description: eg_daemon is a dummy Python-based daemon
### END INIT INFO
# Source function library.
. /etc/rc.d/init.d/functions
if [ -f /etc/sysconfig/eg_daemon ]; then
. /etc/sysconfig/eg_daemon
fi
eg_daemon=/var/lib/eg_daemon/eg_daemon.py
prog=eg_daemon
pidfile=${PIDFILE-/var/run/eg_daemon.pid}
logfile=${LOGFILE-/var/log/eg_daemon.log}
RETVAL=0
OPTIONS=""
start() {
echo -n $"Starting $prog: "
if [[ -f ${pidfile} ]] ; then
pid=$( cat $pidfile )
isrunning=$( ps -elf | grep $pid | grep $prog | grep -v grep )
if [[ -n ${isrunning} ]] ; then
echo $"$prog already running"
return 0
fi
fi
$eg_daemon -p $pidfile -l $logfile $OPTIONS
RETVAL=$?
[ $RETVAL = 0 ] && success || failure
echo
return $RETVAL
}
stop() {
if [[ -f ${pidfile} ]] ; then
pid=$( cat $pidfile )
isrunning=$( ps -elf | grep $pid | grep $prog | grep -v grep | awk '{print $4}' )
if [[ ${isrunning} -eq ${pid} ]] ; then
echo -n $"Stopping $prog: "
kill $pid
else
echo -n $"Stopping $prog: "
success
fi
RETVAL=$?
fi
echo
return $RETVAL
}
reload() {
echo -n $"Reloading $prog: "
echo
}
# See how we were called.
case "$1" in
start)
start
;;
stop)
stop
;;
status)
status -p $pidfile $eg_daemon
RETVAL=$?
;;
restart)
stop
start
;;
force-reload|reload)
reload
;;
*)
echo $"Usage: $prog {start|stop|restart|force-reload|reload|status}"
RETVAL=2
esac
exit $RETVAL
Run Code Online (Sandbox Code Playgroud)
这里有一个完整的例子.
您应该能够更好地理解python-daemon的内部工作原理.
此外,提供的代码还给出了一个简单启动/停止守护进程的init脚本示例.但是,您可以通过使用参数stop再次调用原始函数来启动/停止它:
python original_func.py stop
Run Code Online (Sandbox Code Playgroud)
小智 0
在 Linux 上,您可以通过运行以下命令来停止守护进程:
$ ps -x
Run Code Online (Sandbox Code Playgroud)
找到与你的守护进程相对应的 PID,然后杀死该进程。
| 归档时间: |
|
| 查看次数: |
33581 次 |
| 最近记录: |