3

多数のワーカー プロセスを実行している Python プログラムがあります。これは孤立したプロセスを避けるために適切に処理する必要があるため、すべてのワーカー プロセスをシャットダウンするシグナル ハンドラーを実装しました。

プログラムは多かれ少なかれ次のように開始します。

  1. プロセス プールを開始します (X 個のワーカーを開始します)
  2. シグナルハンドラを登録します ( signal.signal(signal.SIGTERM, my_signal_handler))。SIGINTまた、同じハンドラーを持つ別のシグナル ハンドラーを追加します。
  3. 別のスレッド ポーリング バックエンド (データベース) を開始し、タスクをプロセス プールに追加します。
  4. メイン スレッドで、結果のプロセス プールをポーリングします (multiprocessing.Queue個々のワーカーが結果を追加する結果があります)。

アイデアは、3 と 4 で開始された 2 つの別個のスレッドが、機械を介してタスクを実行し続けるというものです。

これを手動で開始して呼び出すkill -15 <pid>kill -2 <pid>、すべてを正しくシャットダウンすると、プロセスがjoin(). ドキュメントから読み取ると、rinitTERMはプロセスに a を送信し、その後に を送信しCONTます。ただし、これを runit で実行すると、単に標準ok: down: <my_program>: 1s, normally upの .

その後、手動でプロセスを強制終了すると、ログ ファイルでプロセスが正しくシャットダウンされたことを確認できます。私は何を間違っていますか?runit は、virtualenv をアクティブにするために作成した 3 行のシェル スクリプトのみを強制終了するようですが、実際の python プロセスは残します。

「実行」スクリプトを直接実行しても、実行killまたは Ctrl+C ( と同じSIGINT) で正しくシャットダウンできます。

4

1 に答える 1

3

さて、いくつかの広範なテストの後、私はそれを理解しました。

Runit は kill シグナルをrunスクリプトに送信しますが、デフォルトでは伝達されません。確認する必要があるexec python yourscript.pyのは、最後に電話をかけることです。同様に、runスクリプトが別のシェル スクリプト (つまり、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" $@

exec次のスクリプトまたは python 自体に制御を「渡す」ときに呼び出されることに注意してください。

于 2013-08-14T12:26:26.970 に答える