Bashの組み込み機能がCPUを100%まで燃やすのを待ちます。

Bashの組み込み機能がCPUを100%まで燃やすのを待ちます。

少なくともその仕事は起こった。GNUバッシュバージョン4.3.42 x86_64&&GNUバッシュバージョン4.3.11 x86_64

sleep & wait $!単にsleep信号で中断​​する代わりにsleepSIGUSR1)。しかし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+cSIGINTターミナル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>SIGTERMkill -9 <PID>SIGKILL
  • kill -10 <PID>ターミナル 2 で実行すると、組み込みwait機能は中断されますが、test信号がSIGUSR1キャッチされた直後に printet が発生し、ループが続くため、ループから出ることはありません。
  • SendはSIGINT実行ループを中断し、シェルを停止したり、決して中断することなくwait待機/停止状態を維持します。

結論として

SIGINTSIGUSR1手動トラッピングやその他のカスタムトラッピング後は、正しく処理されないか無視されます。これはプロセスがまだ存在することを意味し、これがCPUを消費/加熱したり、シェルを凍結したりする理由です。ターミナル2で実行するとプロセスはシャットダウン/終了し、ターミナル1の制御権を再取得してCPUをリラックスできますkill -15 <PID>kill -9 <PID>

この問題が発生する理由は依然として謎ですが、誰かが後で何が起こっているのかを正確に説明できることを願っています。

おすすめ記事