捕获runit发送的信号(sv stop <id>)</id>

时间:2013-08-13 11:56:38

标签: python runit

我有一个运行许多工作进程的python程序。因为必须正确处理以避免孤立进程,所以我已经实现了一个信号处理程序来关闭所有工作进程。

程序或多或少地启动:

  1. 启动流程池(启动X工人数)
  2. 注册信号处理程序(signal.signal(signal.SIGTERM, my_signal_handler))。我还为SIGINT添加了另一个具有相同处理程序的信号处理程序。
  3. 启动单独的线程轮询后端(数据库)并将任务添加到进程池。
  4. 在主线程上,轮询流程池以获得结果(各个工作人员将结果添加到结果multiprocessing.Queue)。
  5. 这个想法是在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相同)并正确关闭。

1 个答案:

答案 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本身。