Спи за какое -то время петля получает свой собственный пид

StackOverflow https://stackoverflow.com/questions/4452299

  •  10-10-2019
  •  | 
  •  

Вопрос

У меня есть сценарий Bash, который делает некоторую параллельную обработку в цикле. Я не хочу, чтобы параллельный процесс вспыхнул процессор, поэтому я использую команду сна. Вот упрощенная версия.

(while true;do sleep 99999;done)&

Поэтому я выполняю вышеупомянутую строку из приглашения Bash и получаю что -то вроде:[1] 12345

Где [1] номер работы и 12345 это идентификатор процесса (PID) из цикла while. Я делаю kill 12345 и получить:

[1]+  Terminated              ( while true; do
    sleep 99999;
done )

Похоже, весь сценарий был прекращен. Однако я делаю ps aux|grep sleep И обнаружите, что команда сна все еще становится сильной, но со своим собственным пидом! Я могу убить sleep И все кажется в порядке. Однако, если бы я сначала убить сон, то Where Lop начинает новый sleep пид. Это такой удивление для меня, так как сон не параллелен петле. Сам цикл - это единственный путь исполнения.

Итак, у меня есть два вопроса:

  1. Почему команда Sleep получила свой собственный идентификатор процесса?
  2. Как мне легко убить петлю и сон?
Это было полезно?

Решение

  1. Сон получает свой собственный PID Потому что это процесс работает и просто ожидает. Пытаться which sleep Чтобы увидеть, где это.
  2. Вы можете использовать ps -uf Чтобы увидеть дерево процесса в вашей системе. Оттуда вы можете определить, что PPID (родительский пид) оболочки (та, которая работает в петле).

Другие советы

Вы пробовали сделать kill %1, куда 1 Номер, который вы получаете после запуска команды в фоновом режиме?

Я сделал это прямо сейчас после запуска (while true;do sleep 99999;done)& и это правильно прекратило его.

"PS -PPPID" выбирает все процессы с указанным родительским PID, например:

$ (while true;do sleep 99999;done)&
[1] 12345

$ ppid=12345 ; kill -9 $ppid $(ps --ppid $ppid -o pid --no-heading)

Вы можете убить группу процессов.

Чтобы найти группу процесса вашего процесса запуска:

ps --no-headers -o "%r" -p 15864

Затем убейте группу процессов, используя:

kill -- -[PGID]

Вы можете сделать все это в одной команде. Попробуем:

$ (while true;do sleep 99999;done)&
[1] 16151

$ kill -- -$(ps --no-headers -o "%r" -p 16151)
[1]+  Terminated              ( while true; do
    sleep 99999;
done )
  1. Потому что «сон»-это процесс, а не встроенная функция или аналогичная

  2. Вы могли бы сделать следующее:

    (while true;do sleep 99999;done)&
    whilepid=$!
    kill -- -$whilepid
    

Приведенный выше код убивает группу процессов, потому что PID определяется как отрицательное число (например, -123 вместо 123). Кроме того, он использует переменную $!, который хранит пид самого последнего выполненного процесса.

ПРИМЕЧАНИЕ. Когда вы выполняете любой процесс в фоне в интерактивном режиме (т.е. с помощью подсказки командной строки), он создает новую группу процессов, что происходит с вами. Таким образом, относительно легко «убить их всех», потому что вам просто нужно убить всю группу процессов. Однако, когда то же самое сделано в сценарии, он не создает никакой новой группы, потому что все новые процессы принадлежат PID сценария, даже если они выполняются в фоновом режиме (управление заданиями отключено по умолчанию). Чтобы включить управление заданиями в сценарии, вам просто нужно поставить следующее в начале сценария:

#!/bin/bash

set -m

Убить while петля и sleep с использованием $! Вы также можете использовать trap обработчик сигнала внутри подборной.

(trap 'kill ${!}; exit' TERM; while true; do sleep 99999 & wait ${!}; done)&
kill -TERM ${!}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top