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 sleep
para obtener una interrupción sleep
por una señal (comoSIGUSR1). Pero parece que el wait
bash-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+c
envíaSIGINT
al proceso fg en la Terminal 1- por lo tanto, ejecutar
kill -2 <PID>
en la Terminal 2 es lo mismo que presionarctrl+c
en la Terminal 1 - haciendo uno de los dos puntos anterioresantesla ejecución
kill -10 <PID>
en la Terminal 2 se manejaSIGINT
correctamente - haciéndolodespuésLa ejecución
kill -10 <PID>
en la Terminal 2 (enviando señalSIGUSR1
) no se manejaSIGINT
correctamente y genera un comportamiento problemático. - Reemplazar
kill -2 <PID>
en el Terminal 2 (SIGINT
) conkill -15 <PID>
(SIGTERM
) okill -9 <PID>
(SIGKILL
) conduce siempre a un manejo correcto de la señal. - La ejecución
kill -10 <PID>
en la Terminal 2 interrumpe lawait
función incorporada pero no abandona el bucle, ya quetest
se imprime inmediatamente después de que la señalSIGUSR1
queda atrapada y el bucle continúa. - El envío
SIGINT
sale del ciclo de ejecución y congela el shell o nunca se interrumpewait
y permanece esperando/congelado.
Conclusión
SIGINT
no se captura ni se maneja correctamente o se ignora después del reventado manual SIGUSR1
o 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.