wait bash-builtin queima uma CPU a 100 por cento

15

Ocorre pelo menos na versão bash do GNU 4.3.42 x86_64 & & versão bash do GNU 4.3.11 x86_64

Eu uso sleep & wait $! em vez de um simples sleep para obter um sleep que pode ser interrompido por um sinal (como SIGUSR1 ). Mas parece que o wait bash-builtin se comporta de uma 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, eu recebo a sub-rede que queima uma CPU a 100%.

Terminal 1:

pkill -P $(pgrep -P $$)

Você tem alguma ideia sobre por que esse comportamento ocorre?

NB : não há problema quando o 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)

Depois, pegue uma concha congelada.

Uma terceira 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:

^C (ctrl + C)

Depois, pegue uma concha congelada.

    
por parasite 23.06.2016 / 23:28

1 resposta

1

Observações

  • ctrl+c envia SIGINT para o processo fg no Terminal 1
  • portanto, executar kill -2 <PID> no Terminal 2 é o mesmo que bater ctrl+c no Terminal 1
  • fazendo um dos dois pontos acima antes executando kill -10 <PID> no Terminal 2 manipula SIGINT corretamente
  • executá-lo após executar kill -10 <PID> no Terminal 2 (enviar sinal SIGUSR1 ) não manipula SIGINT corretamente e leva ao comportamento problemático
  • A substituição de kill -2 <PID> no Terminal 2 ( SIGINT ) por kill -15 <PID> ( SIGTERM ) ou kill -9 <PID> ( SIGKILL ) leva sempre a corrigir a manipulação de sinal.
  • a execução de kill -10 <PID> no Terminal 2 interrompe o wait incorporado, mas não sai do loop, pois test é imediatamente impressa após o sinal SIGUSR1 ser interceptado e o loop continuar.
  • O envio de SIGINT irrompe do loop de execução e congela o shell ou nunca interrompe wait e permanece em espera / congelado.

Conclusão

SIGINT não foi encontrado e manipulado corretamente ou é ignorado após a interceptação manual de SIGUSR1 ou talvez de qualquer outra interceptação 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 de kill -15 <PID> ou kill -9 <PID> do Terminal 2 encerra / mata 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 está realmente acontecendo atrás das cortinas.

    
por 04.09.2016 / 20:41