warte, bash-builtin verbrennt eine CPU bei 100 Prozent

warte, bash-builtin verbrennt eine CPU bei 100 Prozent

Tritt mindestens aufGNU Bash Version 4.3.42 x86_64&&GNU Bash Version 4.3.11 x86_64

Ich verwende sleep & wait $!anstelle eines einfachen zum Abrufen eines durch ein Signal sleepunterbrechbarensleepSIGUSR1). Aber es scheint, dass sich das waitintegrierte Bash-Programm seltsam verhält, wenn Sie Folgendes ausführen.

Schalter 1:

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

Terminal 2:

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

Schalter 1:

^C (ctrl + C)

Dann bekomme ich die Subshell, die eine CPU zu 100 Prozent verbrennt.

Schalter 1:

pkill -P $(pgrep -P $$)

Haben Sie eine Idee, warum dieses Verhalten auftritt?

Achtung: Es tritt kein Problem auf, wenn cat <(/subshell/)nicht im Hintergrund ist.


Eine andere Möglichkeit, dieses Verhalten zu erleben

Schalter 1:

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

Terminal 2:

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

Schalter 1:

fg
^C (ctrl + C)

Dann besorgen Sie sich eine gefrorene Schale.


Eine dritte Möglichkeit, dieses Verhalten zu erleben

Schalter 1:

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

Terminal 2:

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

Schalter 1:

^C (ctrl + C)

Dann besorgen Sie sich eine gefrorene Schale.

Antwort1

Beobachtungen

  • ctrl+csendet SIGINTan den fg-Prozess im Terminal 1
  • Daher kill -2 <PID>ist die Ausführung in Terminal 2 dasselbe wie das Drücken ctrl+cin Terminal 1
  • einen der beiden oben genannten Punkte ausführenVorAusführung kill -10 <PID>in Terminal 2 funktioniert SIGINTeinwandfrei
  • dabeinachDie Ausführung kill -10 <PID>im Terminal 2 (Senden des Signals SIGUSR1) funktioniert nicht SIGINTkorrekt und führt zu dem problematischen Verhalten
  • Das Ersetzen von ( ) durch ( ) oder ( ) kill -2 <PID>in Klemme 2 führt immer zur korrekten Signalbehandlung.SIGINTkill -15 <PID>SIGTERMkill -9 <PID>SIGKILL
  • Die Ausführung kill -10 <PID>in Terminal 2 unterbricht die waitintegrierte Funktion, verlässt die Schleife jedoch nicht, da testsofort gedruckt wird, nachdem das Signal SIGUSR1abgefangen wurde und die Schleife fortgesetzt wird.
  • Das Senden SIGINTbricht die Ausführungsschleife ab und friert die Shell ein, oder es erfolgt keine Unterbrechung waitund die Shell bleibt im Warte-/Eingefrorenzustand.

Abschluss

SIGINTwird nicht richtig abgefangen und behandelt oder wird nach manuellem Trapping SIGUSR1oder einem anderen benutzerdefinierten Trapping ignoriert. Das bedeutet, dass der Prozess noch existiert und deshalb die CPU frisst/aufheizt oder die Shell einfriert. Das Ausführen von kill -15 <PID>oder kill -9 <PID>von Terminal 2 aus beendet/beendet den Prozess und gibt Ihnen die Kontrolle über Terminal 1 zurück und entspannt Ihre CPU.

Warum dieses Problem auftritt, ist immer noch ein Rätsel, aber ich hoffe, dass jemand genau erklären kann, was hinter den Kulissen wirklich vor sich geht.

verwandte Informationen