Se produit au moins sur GNU bash version 4.3.42 x86_64 && GNU bash version 4.3.11 x86_64
J'utilise sleep & wait $!
au lieu d'un simple sleep
pour obtenir un interruptible sleep
par un signal (comme SIGUSR1 ). Mais il semble que le wait
bash-builtin se comporte de manière étrange lorsque vous exécutez ce qui suit.
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)
Ensuite, j'obtiens le sous-shell qui brûle un processeur à 100%.
Terminal 1:
pkill -P $(pgrep -P $$)
Avez-vous une idée de la raison pour laquelle ce problème se produit?
NB : aucun problème ne se produit lorsque le cat <(/subshell/)
n'est pas en arrière-plan.
Une autre façon de ressentir ce comportement
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)
Ensuite, obtenez une coquille gelée.
Une troisième façon de ressentir ce comportement
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)
Ensuite, obtenez une coquille gelée.
bash
4.4, peut-être que cela pourrait être affecté ici.wait
qui ressemble beaucoup à ceci. J'ai été frappé par cela dans une boucle qui a engendré des sous-processus pour toujours. Cependant, j'ai testé votre scénario le 4.4.20 et c'était toujours un problème. Fait intéressant, lorsque j'ai attaché un débogueur sur une version que j'ai construite, je pouvais voir qu'il tournait en boucle, mais cela avait également pour effet de sortir de celui-ci, et la boucle recommencerait à produire un `` test ''. En d'autres termes: attacher le débogueur l'a empêché de tourner en boucle.Réponses:
Observations
ctrl+c
envoieSIGINT
au processus fg dans le terminal 1kill -2 <PID>
dans le terminal 2 équivautctrl+c
à frapper dans le terminal 1kill -10 <PID>
dans le Terminal 2 gèreSIGINT
correctementkill -10 <PID>
dans le Terminal 2 (envoi de signalSIGUSR1
) ne se gère pasSIGINT
correctement et conduit au comportement problématiquekill -2 <PID>
dans le terminal 2 (SIGINT
) parkill -15 <PID>
(SIGTERM
) oukill -9 <PID>
(SIGKILL
) conduit toujours à une gestion correcte du signal.kill -10 <PID>
dans le Terminal 2 interrompt lawait
intégrée mais ne quitte pas la boucle car elletest
est immédiatement imprimée après que le signalSIGUSR1
est piégé et la boucle continue.SIGINT
sort de la boucle d'exécution et fige le shell ou il n'interrompt jamaiswait
et reste en attente / gelé.Conclusion
SIGINT
n'est pas acheté et géré correctement ou il est ignoré après le piégeage manuelSIGUSR1
ou peut-être tout autre piégeage défini par l'utilisateur. Cela signifie que le processus existe toujours et c'est pourquoi il mange / chauffe le CPU ou gèle le shell. Exécutionkill -15 <PID>
ou àkill -9 <PID>
partir du terminal 2 termine / tue le processus et vous redonne le contrôle sur le terminal 1 et détend votre processeur.Pourquoi ce problème se produit, reste un mystère, mais j'espère que quelqu'un pourra expliquer exactement ce qui se passe réellement derrière les rideaux.
la source