Ocorre pelo menos emGNU bash versão 4.3.42 x86_64&&GNU bash versão 4.3.11 x86_64
Eu uso sleep & wait $!
em vez de um simples sleep
para obter um sleep
sinal interrompível (comoSIGUSR1). Mas parece que o wait
bash-builtin se comporta de maneira estranha quando você executa o seguinte.
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)
Então, recebo o subshell que queima a CPU a 100 por cento.
Terminal 1:
pkill -P $(pgrep -P $$)
Você tem alguma ideia de por que esse comportamento ocorre?
Observação: nenhum problema ocorre quando cat <(/subshell/)
não está em segundo plano.
Outra maneira de experimentar esse comportamento
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)
Então, pegue uma casca congelada.
Uma terceira maneira de vivenciar esse comportamento
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)
Então, pegue uma casca congelada.
Responder1
Observações
ctrl+c
enviaSIGINT
para o processo fg no Terminal 1- portanto, executar
kill -2 <PID>
no Terminal 2 é o mesmo que clicarctrl+c
no Terminal 1 - fazendo um dos dois pontos acimaantesexecutando
kill -10 <PID>
no Terminal 2 manipulaSIGINT
corretamente - Fazendodepoisa execução
kill -10 <PID>
no Terminal 2 (envio de sinalSIGUSR1
) não funcionaSIGINT
corretamente e leva ao comportamento problemático - Substituir
kill -2 <PID>
no Terminal 2 (SIGINT
) porkill -15 <PID>
(SIGTERM
) oukill -9 <PID>
(SIGKILL
) leva sempre ao correto tratamento do sinal. - a execução
kill -10 <PID>
no Terminal 2 interrompe owait
built-in, mas não sai do loop, poistest
é imediatamente impresso após o sinalSIGUSR1
ser capturado e o loop continuar. - O envio
SIGINT
sai do loop de execução e congela o shell ou nunca interrompewait
e fica esperando/congelado.
Conclusão
SIGINT
não é capturado e tratado corretamente ou é ignorado após a captura manual SIGUSR1
ou talvez qualquer outra captura definida pelo usuário. Isso significa que o processo ainda existe e é por isso que ele consome/aquece a CPU ou congela o shell. A execução kill -15 <PID>
ou kill -9 <PID>
a partir do Terminal 2 encerra/elimina o processo e devolve o controle sobre o Terminal 1 e relaxa sua CPU.
Por que esse problema ocorre ainda permanece um mistério, mas espero que alguém possa explicar exatamente o que realmente está acontecendo nos bastidores.