等待 bash-builtin 將 CPU 燒毀至 100%

等待 bash-builtin 將 CPU 燒毀至 100%

至少發生在GNU bash 版本 4.3.42 x86_64&&GNU bash 版本 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
   )&

2 號航廈:

kill -10 /the pid of the subshell, printed by the previous command/

1號航廈:

^C (ctrl + C)

然後,我得到了 100% 消耗 CPU 的子 shell。

1號航廈:

pkill -P $(pgrep -P $$)

您知道為什麼會出現這種行為嗎?

注意cat <(/subshell/):不在後台時不會出現問題。


體驗此行為的另一種方式

1號航廈:

(
   trap 'echo SIGUSR1' SIGUSR1;
   echo $BASHPID;
   while :;do
       sleep 1 &
       wait $!;
       echo test;
   done
)&

2 號航廈:

kill -10 /the pid of the subshell, printed by the previous command/

1號航廈:

fg
^C (ctrl + C)

然後,得到一個冷凍的殼。


體驗這種行為的第三種方式

1號航廈:

(
   trap 'echo SIGUSR1' SIGUSR1;
   echo $BASHPID;
   while :;do
       sleep 1 &
       wait $!;
       echo test;
   done
)

2 號航廈:

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
  • 執行上述兩點之一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 。
  • 發送SIGINT會中斷執行循環並凍結 shell,或者它永遠不會中斷wait並保持等待/凍結狀態。

結論

SIGINT未正確處理或在手動陷印SIGUSR1或任何其他使用者定義的陷印後被忽略。這意味著該進程仍然存在,這就是它消耗/加熱 CPU 或凍結 shell 的原因。從終端 2執行kill -15 <PID>kill -9 <PID>會終止/終止進程,並讓您重新獲得對終端 1 的控制權並放鬆 CPU。

為什麼會出現這個問題,仍然是個謎,但我希望有人能準確地解釋幕後到底發生了什麼事。

相關內容