espera, bash-builtin quema una CPU al 100 por ciento

espera, bash-builtin quema una CPU al 100 por ciento

Ocurre al menos enGNU bash versión 4.3.42 x86_64&&GNU bash versión 4.3.11 x86_64

Utilizo sleep & wait $!en lugar de un simple sleeppara obtener una interrupción sleeppor una señal (comoSIGUSR1). Pero parece que el waitbash-integrado se comporta de una manera extraña cuando ejecuta lo siguiente.

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)

Luego, obtengo el subshell que quema una CPU al 100 por ciento.

Terminal 1:

pkill -P $(pgrep -P $$)

¿Tiene alguna idea de por qué ocurre este comportamiento?

NÓTESE BIEN: no ocurre ningún problema cuando cat <(/subshell/)no está en segundo plano.


Otra forma de experimentar este comportamiento.

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)

Luego, consigue una cáscara congelada.


Una tercera forma de experimentar este comportamiento.

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)

Luego, consigue una cáscara congelada.

Respuesta1

Observaciones

  • ctrl+cenvía SIGINTal proceso fg en la Terminal 1
  • por lo tanto, ejecutar kill -2 <PID>en la Terminal 2 es lo mismo que presionar ctrl+cen la Terminal 1
  • haciendo uno de los dos puntos anterioresantesla ejecución kill -10 <PID>en la Terminal 2 se maneja SIGINTcorrectamente
  • haciéndolodespuésLa ejecución kill -10 <PID>en la Terminal 2 (enviando señal SIGUSR1) no se maneja SIGINTcorrectamente y genera un comportamiento problemático.
  • Reemplazar kill -2 <PID>en el Terminal 2 ( SIGINT) con kill -15 <PID>( SIGTERM) o kill -9 <PID>( SIGKILL) conduce siempre a un manejo correcto de la señal.
  • La ejecución kill -10 <PID>en la Terminal 2 interrumpe la waitfunción incorporada pero no abandona el bucle, ya que testse imprime inmediatamente después de que la señal SIGUSR1queda atrapada y el bucle continúa.
  • El envío SIGINTsale del ciclo de ejecución y congela el shell o nunca se interrumpe waity permanece esperando/congelado.

Conclusión

SIGINTno se captura ni se maneja correctamente o se ignora después del reventado manual SIGUSR1o tal vez mediante cualquier otro reventado definido por el usuario. Eso significa que el proceso todavía existe y es por eso que consume/calienta la CPU o congela el shell. La ejecución kill -15 <PID>o kill -9 <PID>desde la Terminal 2 finaliza/matiza el proceso y le devuelve el control sobre la Terminal 1 y relaja su CPU.

Por qué ocurre este problema sigue siendo un misterio, pero espero que alguien pueda explicar exactamente qué está sucediendo realmente detrás de las cortinas.

información relacionada