По крайней мере, в GNU bash версии 4.3.42 x86_64 && GNU bash версии 4.3.11 x86_64
Я использую sleep & wait $!
вместо простого sleep
для получения прерываемого sleep
сигнала (как SIGUSR1 ). Но кажется, что wait
bash-buildin ведет себя странным образом, когда вы запускаете следующее.
Терминал 1:
cat <(
trap 'echo SIGUSR1' SIGUSR1;
echo $BASHPID;
while :;do
sleep 1 &
wait $!;
echo test;
done
)&
Терминал 2:
kill -10 /the pid of the subshell, printed by the previous command/
Терминал 1:
^C (ctrl + C)
Затем я получаю подоболочку, которая сжигает процессор на 100 процентов.
Терминал 1:
pkill -P $(pgrep -P $$)
Есть ли у вас идеи о том, почему такое поведение происходит?
NB : не возникает проблем, когда cat <(/subshell/)
нет в фоновом режиме.
Еще один способ испытать это поведение
Терминал 1:
(
trap 'echo SIGUSR1' SIGUSR1;
echo $BASHPID;
while :;do
sleep 1 &
wait $!;
echo test;
done
)&
Терминал 2:
kill -10 /the pid of the subshell, printed by the previous command/
Терминал 1:
fg
^C (ctrl + C)
Затем получите замороженную раковину.
Третий способ испытать это поведение
Терминал 1:
(
trap 'echo SIGUSR1' SIGUSR1;
echo $BASHPID;
while :;do
sleep 1 &
wait $!;
echo test;
done
)
Терминал 2:
kill -10 /the pid of the subshell, printed by the previous command/
Терминал 1:
^C (ctrl + C)
Затем получите замороженную раковину.
bash
4.4, возможно, это может повлиять на это.wait
которая выглядит очень похоже на это. Я был поражен этим в цикле, который порождал подпроцессы навсегда. Тем не менее, я проверил ваш сценарий на 4.4.20, и это все еще было проблемой. Интересно, что когда я прикрепил отладчик к версии, которую я построил, я мог видеть, что он зацикливался, но он также имел эффект выхода из него, и цикл снова начал выводить 'test'. Другими словами: присоединение отладчика сделало его остановленным.Ответы:
наблюдения
ctrl+c
отправляетSIGINT
в fg-процесс в Терминале 1kill -2 <PID>
в терминале 2 такое же, как выполнениеctrl+c
в терминале 1kill -10 <PID>
в терминале 2SIGINT
правильно обрабатываетkill -10 <PID>
в Терминале 2 (отправка сигналаSIGUSR1
) не обрабатываетсяSIGINT
правильно и приводит к проблемному поведениюkill -2 <PID>
в клемме 2 (SIGINT
) наkill -15 <PID>
(SIGTERM
) илиkill -9 <PID>
(SIGKILL
) всегда приводит к правильной обработке сигнала.kill -10 <PID>
в терминале 2 прерываетwait
встроенную функцию, но не покидает цикл, посколькуtest
он немедленно выводится после захвата сигналаSIGUSR1
и продолжения цикла.SIGINT
прерывается из цикла выполнения и замораживает оболочку, или она никогда не прерываетсяwait
и остается в ожидании / заморожена.Вывод
SIGINT
не обрабатывается и не обрабатывается правильно, или игнорируется после ручного перехватаSIGUSR1
или, возможно, любого другого пользовательского перехвата. Это означает, что процесс все еще существует, и поэтому он ест / нагревает процессор или замораживает оболочку. Выполнениеkill -15 <PID>
илиkill -9 <PID>
из Терминала 2 завершает / убивает процесс и возвращает вам контроль над Терминалом 1 и ослабляет ваш ЦП.Почему эта проблема возникает, до сих пор остается загадкой, но я надеюсь, что кто-то может точно объяснить, что на самом деле происходит за кулисами.
источник