私はbashのトラップ機能で遊んでいます。以下のスクリプトは、ある種の競合状態を示しています。
#! /bin/bash
set -x
trap sigusr1 USR1
ANCESTOR_PID=$$
function sigusr1
{
num+=1
declare -p num
}
function have_a_child
{
sleep $(echo $((1 + RANDOM % 500)) / 1000 | bc -l) &
wait $!
kill -USR1 $ANCESTOR_PID
}
declare -i i=0
declare -i num=0
while (( i < 100 )); do
have_a_child &
i+=1
done
mkfifo -m 0400 /tmp/test.sh.fifo
read < /tmp/test.sh.fifo
つまり、100個の子プロセスを作成し、0〜500ミリ秒間ランダムに待機状態を維持し、各子プロセスはUSR1単一メッセージを親プロセスに送信します。親がUSR1信号を受信すると、信号は増加します。シリアル番号変数 1.
もし 競争条件なし発生し、すべての子プロセスから送信されたすべてのUSR1信号は、親スクリプトによって処理されます。一つずつ、これシリアル番号変数は100すべての子プロセスが終了したとき。しかし、私は観察したシリアル番号ランダムです。98、93、96...
したがって、ここでは入れ子や関数の再入が進んでいるようです。トラップハンドラが一部のサブプロセスで送信された1つのUSR1信号を処理している間、他のUSR1信号は別のサブプロセスで送信され、おそらく3番目のサブプロセスも関連付けられます。 。
質問:
親がいつ複数のシグナルを受け取るのか、親が複数のハンドラ(たとえば、複数のスレッド)を生成するのか、親がネストされたプロセスロジックを実行しているのかはわかりません。
この競合状態を解決するために使用できるbashメカニズムはありますか?