gpt4 book ai didi

python - 捕获 runit 发送的信号 (sv stop )

转载 作者:行者123 更新时间:2023-11-28 16:42:03 24 4
gpt4 key购买 nike

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

程序开始时大致是这样的:

  1. 启动进程池(启动X个worker)
  2. 注册信号处理程序 ( signal.signal(signal.SIGTERM, my_signal_handler) )。我还为 SIGINT 添加了另一个信号处理程序使用相同的处理程序。
  3. 启动单独的线程轮询后端(数据库)并将任务添加到进程池。
  4. 在主线程上,轮询进程池以获取结果(有一个结果 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 进程。

即使我直接运行“运行”脚本,我也可以运行 kill或 Ctrl+C(与 SIGINT 相同)并正确关闭。

最佳答案

好的,经过一些广泛的测试后,我明白了。

Runit 会将 kill 信号发送到 run 脚本,默认情况下不会传播它。您需要确保最后调用 exec python yourscript.py。同样,如果您的 run 脚本调用另一个 shell 脚本(即激活您的 virtualenv 或类似脚本的脚本),它也必须使用 exec 执行此操作。

示例:

运行:

#!/bin/sh
umask 002
2>&1
exec chpst -uanalytics cliscript router

脚本:

#!/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" $@

注意当我们将控制“传递”给下一个脚本或 python 本身时调用的 exec

关于python - 捕获 runit 发送的信号 (sv stop <id>),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18208487/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com