Tritt mindestens auf GNU bash Version 4.3.42 x86_64 && GNU Bash - Version 4.3.11 x86_64
Ich benutze sleep & wait $!
statt eines einfachen sleep
um eine Unterbrechung sleep
durch ein Signal zu bekommen (als SIGUSR1 ). Aber es wait
sieht so aus, als würde sich die Bash-Funktion auf seltsame Weise verhalten, wenn Sie Folgendes ausführen.
Terminal 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/
Terminal 1:
^C (ctrl + C)
Dann bekomme ich die Subshell, die eine CPU zu 100 Prozent brennt.
Terminal 1:
pkill -P $(pgrep -P $$)
Haben Sie eine Vorstellung davon, warum dieses Verhalten auftritt?
NB : Es tritt kein Problem auf, wenn sich das cat <(/subshell/)
nicht im Hintergrund befindet.
Ein anderer Weg, um dieses Verhalten zu erleben
Terminal 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/
Terminal 1:
fg
^C (ctrl + C)
Dann holen Sie sich eine gefrorene Schale.
Ein dritter Weg, um dieses Verhalten zu erleben
Terminal 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/
Terminal 1:
^C (ctrl + C)
Dann holen Sie sich eine gefrorene Schale.
bash
4.4 geändert haben. Vielleicht könnte dies hier betroffen sein.wait
, das dem sehr ähnlich sieht. Das traf mich in einer Schleife, die für immer Unterprozesse hervorbrachte. Ich habe Ihr Szenario jedoch auf 4.4.20 getestet und es war immer noch ein Problem. Interessanterweise , wenn ich einen Debugger an einer Version angebracht ich gebaut, konnte ich sehen , es wurde Umschlingung, aber es auch hatte die Wirkung , brechen aus ihm heraus, und die Schleife beginnen würde wieder ausgibt ‚test‘. Mit anderen Worten: Durch das Anhängen des Debuggers wurde das Schleifen beendet.Antworten:
Beobachtungen
ctrl+c
SendetSIGINT
an den FG-Prozess in Terminal 1kill -2 <PID>
in Terminal 2 entspricht daher der Ausführungctrl+c
in Terminal 1kill -10 <PID>
in Terminal 2SIGINT
korrekt ausführenkill -10 <PID>
in Terminal 2 (Signal sendenSIGUSR1
) nichtSIGINT
richtig und führt zu einem problematischen Verhaltenkill -2 <PID>
von Klemme 2 (SIGINT
) durchkill -15 <PID>
(SIGTERM
) oderkill -9 <PID>
(SIGKILL
) führt immer zu einer korrekten Signalbehandlung.kill -10 <PID>
in Terminal 2 unterbricht diewait
eingebaute Schleife, verlässt sie jedoch nicht, da sietest
sofort gedruckt wird, nachdem das Signal abgefangen wurdeSIGUSR1
und die Schleife fortgesetzt wird.SIGINT
unterbricht die Ausführungsschleife und friert die Shell ein oder sie unterbricht sie niewait
und bleibt warten / eingefroren.Fazit
SIGINT
wird nicht richtig erfasst und behandelt oder nach manuellem ÜberfüllenSIGUSR1
oder anderen benutzerdefinierten Überfüllungen ignoriert . Das bedeutet, dass der Prozess noch vorhanden ist und deshalb die CPU aufgefressen / aufgeheizt oder die Shell eingefroren wird. Das Ausführen vonkill -15 <PID>
oderkill -9 <PID>
von Terminal 2 beendet / beendet den Prozess und gibt Ihnen die Kontrolle über Terminal 1 zurück und entspannt Ihre CPU.Warum dieses Problem auftritt, bleibt immer noch ein Rätsel, aber ich hoffe, jemand kann genau erklären, was sich wirklich hinter den Kulissen abspielt.
quelle