Убейте все 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