6

いくつかのバックグラウンドプロセスを生成するbashスクリプトを書いています。プロセスが終了するたびに通知を受け取りたいのですが。終了したプロセスのpidを知りたいのですが。

waitスポーンされた各プロセスのpidがキャプチャされて配列に格納され、配列が繰り返され、各プロセスで待機が呼び出されるように、を使用することを検討しました。この手法は、ここでさまざまな方法で説明されています。

https://stackoverflow.com/a/356154/366856

これに関する問題は、私が正しく理解していれば、個々のプロセスが終了したらすぐに何らかのアクションを実行したい場合、比較的非効率になる可能性があることです。たとえば、プロセスAとBを生成し、BがAの前に終了した場合、実行はAとBの両方が終了するのを待つ必要があります。Bが終了したらすぐにアクションを実行する必要があります。

子が終了したらすぐにアクションを実行する方法のようtrap SIGCHLDですが、問題は、SIGCHLD信号のソースのpidを判別する方法が見つからないことです。これも必要です。これの実用的な例に私が見つけた最も近いものは、この投稿の3番目のコード例です。

http://www.linuxforums.org/forum/programming-scripting/103996-multithreading-bash.html#post510187

便宜上、ここにコピーして貼り付けました。

#!/bin/bash

iNext=0

function ChildReturned() {
        wait $1
        echo "$1 was returned. Its exits status was: $?"
        iNext=$((iNext+1))
        StartChild $iNext
}


function StartChild {
        ./child $1 &
        pid=$!
        echo "Started: $1  PID= $pid"
        trap 'ChildReturned $pid' SIGCHLD
}


set -bm

for (( iNext=0; iNext<=10; iNext++ ));
do
        StartChild $iNext
done

wait

この例はうまくいかないと思います。なぜなら、作成者は、引数trapで異なるpid変数をキャプチャするたびに、何度も呼び出すという間違いを犯しているからです。trapトラップが呼び出されるたびに、前の呼び出しが上書きされるため、任意のpidがキャプチャされます。私はより良いテクニックを見つけることができませんでした。

bashのトラップを使用して終了した子プロセスのpidを取得する方法はありますか?

アップデート

私はこのリソースを指摘したかっただけです。このリソースには、これまでに見たこの問題の解決策の最も包括的な概要が含まれています。

http://mywiki.wooledge.org/ProcessManagement#I_want_to_process_a_bunch_of_files_in_parallel.2C_and_when_one_finishes.2C_I_want_to_start_the_next._And_I_want_to_make_sure_there_are_exactly_5_jobs_running_at _

4

1 に答える 1

3

トラップを1回設定すると、トラップ内で呼び出しjobs -nて、最後にチェックしてからどの子が終了したかを確認できます。これは、どの子がSIGCHLDを送信したかを示していないことに注意してください。あなたが罠に入る前に2人の子供が死んだ場合を考えてみてください。その場合、あなたは一度だけ罠に入るでしょう、そしてそれはあなたが実際に反応している子供の合図である論点です。これ-nはbash拡張機能であり、を使用することをお勧めしますjobs -l

于 2012-03-02T17:56:17.143 に答える