Убейте все R-процессы, которые зависают более минуты
Я использую crontask для регулярного запуска Rscript. К сожалению, мне нужно сделать это на небольшом экземпляре aws, и процесс может зависать, создавая все больше и больше процессов друг над другом, пока вся система не будет отставать.
Я хотел бы написать crontask, чтобы убить все R-процессы, длившиеся более одной минуты. Я нашел еще один ответ на Stack Overflow, который я адаптировал, что, думаю, решит проблему. Я придумал:
if [[ "$(uname)" = "Linux" ]];then killall --older-than 1m "/usr/lib/R/bin/exec/R --slave --no-restore --file=/home/ubuntu/script.R";fi
Я скопировал задачу непосредственно из htop, но она не работает, как я ожидаю. Я получаю ошибку No such file or directory
, но я проверил ее несколько раз.
Мне нужно убить все R-процессы, длившиеся дольше минуты. Как я могу это сделать?
Ответы
Ответ 1
Возможно, вы захотите избежать убийства процессов у другого пользователя и попробуйте SIGKILL (kill -9
) после SIGTERM (kill -15
). Вот script, который вы можете выполнять каждую минуту с заданием CRON:
#!/bin/bash
PROCESS="R"
MAXTIME=`date -d '00:01:00' +'%s'`
function killpids()
{
PIDS=`pgrep -u "${USER}" -x "${PROCESS}"`
# Loop over all matching PIDs
for pid in ${PIDS}; do
# Retrieve duration of the process
TIME=`ps -o time:1= -p "${pid}" |
egrep -o "[0-9]{0,2}:?[0-9]{0,2}:[0-9]{2}$"`
# Convert TIME to timestamp
TTIME=`date -d "${TIME}" +'%s'`
# Check if the process should be killed
if [ "${TTIME}" -gt "${MAXTIME}" ]; then
kill ${1} "${pid}"
fi
done
}
# Leave a chance to kill processes properly (SIGTERM)
killpids "-15"
sleep 5
# Now kill remaining processes (SIGKILL)
killpids "-9"
Ответ 2
Зачем подразумевать дополнительный процесс каждую минуту с помощью cron?
Не было бы легче запустить R с тайм-аутом от coreutils, тогда процессы будут автоматически уничтожены после выбранного вами времени.
timeout [option] duration command [arg]…
Ответ 3
Я думаю, что лучший вариант - это сделать с помощью R
. Я не эксперт, но кажется, что пакет future
позволит выполнить функцию в отдельном thread
. Вы можете запустить фактическую задачу в отдельном потоке, а в режиме основного потока - 60 секунд, а затем stop()
.
Предыдущее обновление
user1747036 answer, который рекомендует timeout
- лучшая альтернатива.
Мой оригинальный ответ
Этот вопрос более подходит для суперпользователя, но вот что-то не так с
if [[ "$(uname)" = "Linux" ]];then
killall --older-than 1m \
"/usr/lib/R/bin/exec/R --slave --no-restore --file=/home/ubuntu/script.R";
fi
-
Аргумент name
- это либо имя изображения, либо путь к нему. Вы также включили в него параметры
-
Если -s signal
не указано killall
отправляет SIGTERM
, который может игнорировать ваш процесс. Можете ли вы убить длинный script с этим в командной строке? Вам может понадобиться SIGKILL
/-9
Подробнее в http://linux.die.net/man/1/killall