少なくともGNU bashバージョン4.3.42 x86_64で発生&&GNU bashバージョン4.3.11 x86_64
シグナルによって割り込み可能なsleep
を取得するために、単純なsleep
ではなく_sleep & wait $!
_を使用します(SIGUSR1として)。しかし、以下を実行すると、wait
bash-builtinが奇妙な動作をするようです。
_cat <(
trap 'echo SIGUSR1' SIGUSR1;
echo $BASHPID;
while :;do
sleep 1 &
wait $!;
echo test;
done
)&
_
_kill -10 /the pid of the subshell, printed by the previous command/
_
_^C (ctrl + C)
_
次に、CPUを100%燃焼させるサブシェルを取得します。
_pkill -P $(pgrep -P $$)
_
この動作が発生する理由について何か考えがありますか?
[〜#〜] nb [〜#〜]:cat <(/subshell/)
がバックグラウンドにない場合、問題は発生しません。
_(
trap 'echo SIGUSR1' SIGUSR1;
echo $BASHPID;
while :;do
sleep 1 &
wait $!;
echo test;
done
)&
_
_kill -10 /the pid of the subshell, printed by the previous command/
_
_fg
^C (ctrl + C)
_
次に、凍結したシェルを入手します。
_(
trap 'echo SIGUSR1' SIGUSR1;
echo $BASHPID;
while :;do
sleep 1 &
wait $!;
echo test;
done
)
_
_kill -10 /the pid of the subshell, printed by the previous command/
_
_^C (ctrl + C)
_
次に、凍結したシェルを入手します。
観測
ctrl+c
は、SIGINT
をターミナル1のfgプロセスに送信しますkill -2 <PID>
を実行することは、ターミナル1でctrl+c
を押すことと同じです。kill -10 <PID>
を実行する前にbeforeを実行すると、SIGINT
が正しく処理されますkill -10 <PID>
を実行すると(信号SIGUSR1
を送信)、SIGINT
が正しく処理されず、問題が発生します動作SIGINT
)のkill -2 <PID>
をkill -15 <PID>
(SIGTERM
)またはkill -9 <PID>
(SIGKILL
)に置き換えると、常に正しい信号処理が行われます。kill -10 <PID>
を実行すると、wait
組み込みが中断されますが、test
は、信号SIGUSR1
がトラップされてループが継続した直後に印刷されるため、ループを終了しません。SIGINT
を送信すると、実行中のループが抜けてシェルがフリーズするか、wait
が中断されずに待機/フリーズされたままになります。結論
SIGINT
が取得されず、正しく処理されないか、手動でSIGUSR1
をトラップしたり、他のユーザー定義のトラップを実行した後に無視されます。これは、プロセスがまだ存在していることを意味し、CPUを消費または加熱したり、シェルを凍結したりします。ターミナル2からkill -15 <PID>
またはkill -9 <PID>
を実行すると、プロセスが終了/終了し、ターミナル1の制御が戻され、CPUが解放されます。
なぜこの問題が発生するのか、それでも謎のままですが、誰かがカーテンの裏側で実際に何が起こっているのかを正確に説明できれば幸いです。