
少なくともその仕事は起こった。GNUバッシュバージョン4.3.42 x86_64&&GNUバッシュバージョン4.3.11 x86_64
sleep & wait $!
単にsleep
信号で中断する代わりにsleep
SIGUSR1)。しかしwait
、次のコマンドを実行すると、bash-builtinが奇妙に動作するようです。
ターミナル1:
cat <(
trap 'echo SIGUSR1' SIGUSR1;
echo $BASHPID;
while :;do
sleep 1 &
wait $!;
echo test;
done
)&
NO2。ターミナル:
kill -10 /the pid of the subshell, printed by the previous command/
ターミナル1:
^C (ctrl + C)
その後、サブシェルがCPUを100%消費するようになりました。
ターミナル1:
pkill -P $(pgrep -P $$)
なぜこれが起こるのか知っていますか?
気づくcat <(/subshell/)
:バックグラウンドにないときは問題ありません。
この行動を経験する別の方法
ターミナル1:
(
trap 'echo SIGUSR1' SIGUSR1;
echo $BASHPID;
while :;do
sleep 1 &
wait $!;
echo test;
done
)&
NO2。ターミナル:
kill -10 /the pid of the subshell, printed by the previous command/
ターミナル1:
fg
^C (ctrl + C)
その後、冷凍シェルを取得します。
この動作を体験する第3の方法
ターミナル1:
(
trap 'echo SIGUSR1' SIGUSR1;
echo $BASHPID;
while :;do
sleep 1 &
wait $!;
echo test;
done
)
NO2。ターミナル:
kill -10 /the pid of the subshell, printed by the previous command/
ターミナル1:
^C (ctrl + C)
その後、冷凍シェルを取得します。
答え1
観察結果
ctrl+c
SIGINT
ターミナル1のfg-processに送る- したがって、ターミナル2で実行することは、ターミナル1で
kill -2 <PID>
実行するのと同じです。ctrl+c
- 上記の2つのいずれかを実行します。今後
kill -10 <PID>
第2ターミナルでSIGINT
正しい処理を行います。 - 行為後ろに
kill -10 <PID>
ターミナル2で実行(シグナルを送信SIGUSR1
)がSIGINT
正しく処理されないため、問題のある動作が発生します。 kill -2 <PID>
ターミナル2で()を()または()SIGINT
に置き換えると、常に正しい信号処理が行われます。kill -15 <PID>
SIGTERM
kill -9 <PID>
SIGKILL
kill -10 <PID>
ターミナル 2 で実行すると、組み込みwait
機能は中断されますが、test
信号がSIGUSR1
キャッチされた直後に printet が発生し、ループが続くため、ループから出ることはありません。- Sendは
SIGINT
実行ループを中断し、シェルを停止したり、決して中断することなくwait
待機/停止状態を維持します。
結論として
SIGINT
SIGUSR1
手動トラッピングやその他のカスタムトラッピング後は、正しく処理されないか無視されます。これはプロセスがまだ存在することを意味し、これがCPUを消費/加熱したり、シェルを凍結したりする理由です。ターミナル2で実行するとプロセスはシャットダウン/終了し、ターミナル1の制御権を再取得してCPUをリラックスできますkill -15 <PID>
。kill -9 <PID>
この問題が発生する理由は依然として謎ですが、誰かが後で何が起こっているのかを正確に説明できることを願っています。