Se produce al menos en GNU bash versión 4.3.42 x86_64 && GNU bash versión 4.3.11 x86_64
Utilizo en sleep & wait $!
lugar de un simple sleep
para obtener un interrumpible sleep
por una señal (como SIGUSR1 ). Pero parece que wait
bash-builtin 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)
Entonces, obtengo el subshell que quema una CPU al 100 por ciento.
Terminal 1:
pkill -P $(pgrep -P $$)
¿Tienes alguna idea de por qué ocurre este comportamiento?
NB : no se produce 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.
bash
4.4, tal vez esto podría verse afectado.wait
que se parece mucho a esto. Fui golpeado por eso en un bucle que generó subprocesos para siempre. Sin embargo, probé su escenario en 4.4.20 y todavía era un problema. Curiosamente, cuando adjunté un depurador en una versión que construí, pude ver que estaba dando vueltas, pero también tuvo el efecto de salir de él, y el bucle comenzaría a generar 'prueba' nuevamente. En otras palabras: adjuntar el depurador hizo que dejara de girar.Respuestas:
Observaciones
ctrl+c
envíaSIGINT
al proceso fg en la Terminal 1kill -2 <PID>
en la Terminal 2 es lo mismo que golpearctrl+c
en la Terminal 1kill -10 <PID>
en la Terminal 2 manejaSIGINT
correctamentekill -10 <PID>
en la Terminal 2 (enviar señalSIGUSR1
) no se manejaSIGINT
correctamente y conduce al comportamiento problemáticokill -2 <PID>
en la Terminal 2 (SIGINT
) conkill -15 <PID>
(SIGTERM
) okill -9 <PID>
(SIGKILL
) conduce siempre para corregir el manejo de la señal.kill -10 <PID>
en la Terminal 2 interrumpe lawait
construcción pero no abandona el bucle ya quetest
se imprime inmediatamente después de que la señalSIGUSR1
queda atrapada y el bucle continúa.SIGINT
sale del bucle de ejecución y congela el shell o nunca se interrumpewait
y permanece esperando / congelado.Conclusión
SIGINT
no se busca y maneja correctamente o se ignora después de la captura manualSIGUSR1
o tal vez cualquier otra captura definida por el usuario. Eso significa que el proceso aún existe y es por eso que consume / calienta la CPU o congela el shell. Ejecutarkill -15 <PID>
okill -9 <PID>
desde la Terminal 2 finaliza / mata 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 lo que realmente está sucediendo detrás de las cortinas.
fuente