Występuje przynajmniej w wersji GNU bash 4.3.42 x86_64 i & GNU bash wersja 4.3.11 x86_64
Używam sleep & wait $!
zamiast prostego sleep
do uzyskania przerwania sleep
przez sygnał (jako SIGUSR1 ). Ale wygląda na to, że wait
wbudowane bash zachowuje się w dziwny sposób, gdy uruchomisz następujące.
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)
Następnie otrzymuję podpowłokę, która spala procesor w 100 procentach.
Terminal 1:
pkill -P $(pgrep -P $$)
Czy masz pojęcie o tym, dlaczego tak się dzieje?
Uwaga : nie występuje problem, gdy cat <(/subshell/)
nie ma go w tle.
Kolejny sposób, aby doświadczyć tego zachowania
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)
Następnie weź zamrożoną skorupę.
Trzeci sposób na doświadczenie tego zachowania
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)
Następnie weź zamrożoną skorupę.
bash
4.4, może to tutaj mieć wpływ.wait
który wygląda bardzo podobnie do tego. Uderzyło mnie to w pętli, która odrodziła podprocesy na zawsze. Jednak przetestowałem twój scenariusz w dniu 4.4.20 i nadal był problem. Co ciekawe, kiedy dołączyłem debugger do zbudowanej przeze mnie wersji, widziałem, że się zapętla, ale miał również efekt wyrwania się z niego, a pętla znów zaczyna „testować”. Innymi słowy: dołączenie debuggera sprawiło, że przestał on spinloopować.Odpowiedzi:
Spostrzeżenia
ctrl+c
wysyłaSIGINT
do procesu fg w Terminalu 1kill -2 <PID>
w Terminalu 2 jest tym samym, co trafieniectrl+c
w Terminalu 1kill -10 <PID>
w uchwytach terminala 2SIGINT
kill -10 <PID>
w Terminalu 2 (wysyłanie sygnałuSIGUSR1
) nie obsługujeSIGINT
poprawnie i prowadzi do problematycznego zachowaniakill -2 <PID>
w Terminalu 2 (SIGINT
) nakill -15 <PID>
(SIGTERM
) lubkill -9 <PID>
(SIGKILL
) zawsze prowadzi do poprawnej obsługi sygnału.kill -10 <PID>
w Terminalu 2 przerywawait
wbudowane, ale nie opuszcza pętli, ponieważtest
jest natychmiast drukowane poSIGUSR1
uwięzieniu sygnału i kontynuowaniu pętli.SIGINT
przerywa wykonywanie pętli i zamraża powłokę lub nigdy nie przerywawait
i pozostaje w oczekiwaniu / zamrożone.Wniosek
SIGINT
nie jest traktowany i obsługiwany poprawnie lub jest ignorowany po ręcznym pułapkowaniuSIGUSR1
lub innym pułapkom zdefiniowanym przez użytkownika. Oznacza to, że proces nadal istnieje i dlatego zjada / nagrzewa procesor lub zamraża powłokę. Wykonywaniekill -15 <PID>
lubkill -9 <PID>
z Terminalu 2 kończy / zabija proces i daje ci kontrolę nad Terminalem 1 i odpręża procesor.Dlaczego ten problem występuje, nadal pozostaje tajemnicą, ale mam nadzieję, że ktoś może dokładnie wyjaśnić, co naprawdę dzieje się za zasłonami.
źródło