我有一个运行许多工作进程的python程序。因为必须正确处理以避免孤立进程,所以我已经实现了一个信号处理程序来关闭所有工作进程。
程序或多或少地启动:
signal.signal(signal.SIGTERM, my_signal_handler)
)。我还为SIGINT
添加了另一个具有相同处理程序的信号处理程序。multiprocessing.Queue
)。这个想法是在3和4中启动的两个单独的线程使任务在机器中运行。
如果我手动启动并调用kill -15 <pid>
或kill -2 <pid>
,则会正确关闭所有内容,等待join()
进程。从文档中读取,runit会向流程发送TERM
,然后是CONT
。但是,在runit下运行它,它只显示标准ok: down: <my_program>: 1s, normally up
,但该进程仍然在后台运行(即使是主进程,它也是UNTOUCHED)。
如果我之后出去并手动终止进程,我可以在日志文件中看到它正确关闭。我究竟做错了什么?似乎runit只会杀死我为激活virtualenv而创建的3行shell脚本,但是留下了实际的python进程。
即使我运行&#34;运行&#34;脚本直接,我可以运行kill
或Ctrl + C(与SIGINT
相同)并正确关闭。
答案 0 :(得分:3)
好的,经过一些广泛的测试,我发现了它。
Runit会将kill信号发送到run
脚本,默认情况下不会传播它。您需要确保最后致电exec python yourscript.py
。同样,如果您的run
脚本调用另一个shell脚本(即激活您的virtualenv或类似脚本),它也必须使用exec
。
样品:
run
:
#!/bin/sh
umask 002
2>&1
exec chpst -uanalytics cliscript router
cliscript
:
#!/bin/sh
# Resolve script path, assuming that the script resides in $(ABSPATH)/bin
SCRIPTPATH="$0"
if [ -h "$SCRIPTPATH" ]; then
SCRIPTPATH=$(readlink -e "$0")
fi
ABSPATH=$(dirname "$(cd "$(dirname "$SCRIPTPATH")"; pwd -L)")
# Load the virtual environment
source "$ABSPATH/venv/bin/activate"
# Set up environment
export PYTHONUNBUFFERED=1
exec python "$ABSPATH/bin/processing-cli.py" $@
注意当我们&#34;通过&#34;时被调用的exec
控制到下一个脚本或python本身。