В чем разница между Ctrl-Z и kill -STOP?

14

Когда я запускаю команду ( makeдля большого проекта) из оболочки, я могу нажать Ctrl-Z, чтобы остановить процесс и вернуться в оболочку. Впоследствии я могу бежать, fgчтобы продолжить процесс.

Я пытаюсь написать сценарий оболочки, чтобы автоматизировать это (в частности, проверять температуру моего процессора каждые несколько секунд и останавливать процесс, если он становится слишком горячим, так как мой компьютер подвержен перегреву). Моя первая попытка работала так (упрощенно):

make &
subpid="$!"

sleep 2
# If the CPU temperature is too high...
kill -STOP "$subpid"

sleep 2
# If the CPU temperature has dropped to safe levels...
kill -CONT "$subpid"

wait "$subpid"

К сожалению, это не сработало; отправка SIGSTOP процессу не приостановила его (что стало очевидным из продолжения отправки вывода на терминал). Я запустил make &командную строку, отправил SIGSTOP и проверил состояние процесса с помощью ps; он был указан как остановленный (и снова начался, когда я отправлял SIGCONT), но он все еще извергал выходной поток и повышал температуру ядра! Остановка с помощью Ctrl-Z никогда не имела этой проблемы, но я не знаю, как это сделать в скрипте.

Чем отличается Ctrl-Z от других kill -STOP, и как я могу получить поведение первого в сценарии оболочки?

Taymon
источник
И да, makeзапускается рекурсивно. На самом деле, я думаю, что это несколько уровней.
Таймон

Ответы:

12

Чем отличается Ctrl-Z от других kill -STOP, и как я могу получить поведение первого в сценарии оболочки?

CTRL-Zобычно отправляет SIGTSTP (который может быть заблокирован), и, помимо прочего, оболочки часто сбрасывают tty в ранее сохраненное состояние в этих случаях. Однако, что более важно, для группы процессов управляющего терминала задан PID оболочки (а затем снова PID задания, возобновленного с fg).

Вернемся к исходной проблеме: использование частотно-зависимого масштабирования, такого как, например, Cpufreqd, может быть лучшим молотком для вашего ногтя.

peterph
источник
4

Вы не хотите останавливать makeпроцесс; Вы хотите остановить makeпроцесс и все его дочерние процессы. Могу поспорить, что make запускался рекурсивно.

Вы можете попробовать set -m, а затем использовать %1вместо "$subpid".

set -mПозволяет «контролировать работу», которая по умолчанию отключена скриптов внутри. Я думаю, что это должно работать для вашего случая использования, хотя люди, кажется, думают, что это плохая идея в целом .

sourcejedi
источник
4

Вы можете отправить сигнал всем процессам в группе процессов, если вы укажете отрицательное значение PID - PGID лидера сеанса.

kill -STOP -"$subpid"

Примечание. Для запуска программы в новом сеансе используйте setsid make. Но в твоем случае я думаю, что это не нужно. Однако, если make запускается рекурсивно, каждый экземпляр make может быть своим собственным лидером (я не уверен в этом).

Другим вариантом может быть использование killall:

killall -STOP make

Разница между Ctrl + Z и kill -STOP:

  • Ctrl-Z фактически отправляет TSTP, который можно заблокировать.
  • СТОП не может быть заблокирован.
Jurij
источник
PGID подход не сделал работу, и подготовил следующую строку вывода: /usr/local/bin/myscript: line 38: kill: (-10202) - No such process. Фоновые процессы продолжали выполняться. Я не думаю, что killallподход будет работать, потому что некоторые из подпроцессов кажутся shскорее, чем make.
Таймон
Кажется, процесс, на который вы посылаете сигнал, уже завершен. Подпроцессы с именем sh порождаются make. В вашем случае с make и многими подпроцессами лучше всего было бы получить PID всех детей и ОСТАНОВИТЬ их всех.
Юрий
Это сработало, когда я сделал это вручную из оболочки, но не в сценарии оболочки. Я думаю, это потому, что когда я делал это вручную, корневой PID (от которого другие унаследовали свои PGID) был идентификатором первой makeкоманды, но когда я делал это из сценария, корневой PID был из самого сценария оболочки ,
Таймон
1

Ctrl+ Cиспользуется для уничтожения процесса с помощью сигнала SIGINT, другими словами, это вежливое уничтожение .

Ctrl+ Z используется для приостановки процесса, посылая ему сигнал SIGSTP , который похож на сигнал ожидания , который можно отменить, и процесс можно возобновить снова.

Однако, когда процесс приостанавливается, мы можем возобновить его снова с помощью fg (возобновить на переднем плане) и bg (возобновить в фоновом режиме) , но я не могу возобновить остановленный процесс, в этом разница между использованием Ctrl+ C& Ctrl+ Z.

Как просмотреть приостановленный процесс?

Когда у вас есть несколько приостановленных команд, для их перечисления вы используете jobsкоманду, и результат будет:

[1]-  Stopped                 cat
[2]+  Stopped                 vi

Как убить приостановленный процесс в фоновом режиме?

Используя killкоманду:

kill %nгде п есть номер задания (один в квадратных скобках с выхода рабочих мест), поэтому я хочу , чтобы убить кошку: kill %1.

antzshrek
источник