
私は非常に複雑なPythonアプリケーションを持っています。独自の初期化スクリプトがありますが、実行すると次のようになります。
sudo service my_service_daemon stop
「Stopping my_service_daemon [OK]」が印刷されますが、ジョブが完了するまで実際の子プロセスに残ります(信号15をキャプチャしますが、いくつかの操作を実行する必要があります)。したがって、子プロセスがまったくない場合にのみ「[OK]」メッセージを印刷したいと思います。これはinitスクリプトの一部です(CentOS 6で実行されています)。
...
. /etc/init.d/functions
...
stop(){
echo -n $"Stopping $prog: "
if [ -a $pidfile ]; then
group_id=$(ps -o pgid= $(cat $pidfile) | grep -o [0-9]*)
if [ ! -z $group_id ]; then
kill -- -$group_id
success
fi
else
failure
fi
RETVAL=$?
echo
[ $RETVAL = 0 ] && rm -f $lockfile $pidfile
}
答え1
プロセス処理を使用するsystemd
か、cgroup
子動物園を手動で制御します。出力ファイルps(1)
とPIDファイルを操作すると、レースが簡単に発生する可能性があり、髪を引っ張って早期ハゲを引き起こすことが知られています。
答え2
完了したら、kill -- -$group_id
すべてのプロセスが終了するまで待ちます。たとえば、私は次のことをします。
...
if [ ! -z "$group_id" ]; then
kill -- -$group_id
while pgrep -g $group_id &>/dev/null; do
sleep 1
done
success
...
これにより、プロセスグループ()のすべてのメンバーがpgrep
検索されます。通常、これらすべてのPIDを画面に印刷しますが、私たちはそれを見たくないので、すべての出力にリダイレクトしました。検索基準に一致するプロセスが1つ以上見つかった場合、正常に終了します()。サイクルを維持し続けます。プロセスが見つからない場合は「false」()で終了し、ループを終了してその行に到達します。堅いループのためにシステムが破壊されないようにシステムを挿入しました。-g
$group_id
/dev/null
pgrep
0
while
1
success
sleep 1
答え3
Pythonアプリケーションでファイルを開いたままにします。つまり、実行プログラムスクリプトでそれをオンにし、アプリケーションでオフにしないでください。
このファイルはPIDファイルです。概念証明(並行性を扱わない):
pidfile=/var/run/myapp.pid
logfile=/var/log/myapp.log
start () {
sh -c 'echo $$ >"$1"; exec myapp <"$1" >/dev/null 2>"$2"' &
}
stop () {
master_pid=$(cat "$pidfile")
while
case " $(fuser "$pidfile" 2>/dev/null) " in
*" $master_pid "*)
echo "Master process is alive, killing it"
kill "$master_pid";;
" ") echo "Master process is dead and no subprocesses remain"; false;;
*) echo "Master process is already dead but some processes remain";;
esac
do
sleep 1
done
rm "$pidfile"
}