Как ограничить время запуска программы в Linux?

10

У меня есть несколько симуляций, каждая из которых вызывается python simulate.py <parameter list>. Проблема этих симуляций в том, что некоторые из них зависают без выхода, что не позволяет мне запускать их в пакетном режиме с помощью простого скрипта.

То, что мне нужно, это какая-то форма команды «run-time-constraint», которая автоматически убивает процесс (предпочтительно виртуальным нажатием Ctrl + C , но я думаю, что простое уничтожение тоже подойдет) после определенного времени, если процесс не закончился изящно сам по себе.

Конечно , я могу написать такой скрипт сам, но я подозреваю , что кто - то сделал это уже до меня, поэтому я не придется изобретать велосипед тратить часы с ps, timeи Баш руководства.

Адам Рычковски
источник

Ответы:

15

Потенциальное решение № 1

Используйте timeoutкоманду:

$ date
Mon May  6 07:35:07 EDT 2013
$ timeout 5 sleep 100
$ date
Mon May  6 07:35:14 EDT 2013

Вы можете также добавить timeoutкоманду в killпроцесс, если он не остановился через некоторое время.

$ date
Mon May  6 07:40:40 EDT 2013
$ timeout -k 20 5 sleep 100
$ date
Mon May  6 07:40:48 EDT 2013

Это будет ждать до 20 секунд после того, как процесс sleep 100должен был остановиться, если он все еще работает, то timeoutотправит ему killсигнал.

Потенциальное решение № 2

Альтернативный способ, хотя и более рискованный, может быть следующим:

./myProgram &
sleep 1
kill $! 2>/dev/null && echo "myProgram didn't finish"

Нашел эту технику в переполнении стека в вопросе: Ограничение времени работы программы в Linux . Конкретно это ответ .

ПРИМЕЧАНИЕ. Согласно комментарию, оставленному @mattdm, приведенный выше метод может быть рискованным, учитывая, что он предполагает, что никаких новых процессов не было запущено со времени вашего процесса. Таким образом, новые PID не были назначены. Учитывая это, этот подход, вероятно, не следует использовать, но он приведен здесь только в качестве ссылки для общего подхода к проблеме. timeoutМетод является лучшим вариантом из 2.

SLM
источник
Но тогда будет гарантировано, что сценарий всегда будет занимать все это время. В моем случае это не 1 секунда, а 15 минут.
Адам Рычковски
Но другое решение, найденное в этом вопросе, должно быть именно тем, что мне нужно. Спасибо!
Адам Рычковски
2
Предположим, что myProgram заканчивается за меньшее время, чем sleep(не является необоснованным предположением, поскольку цель состоит в том, чтобы установить максимально допустимое время выполнения). Затем вы отправляете сигнал либо на несуществующий PID (без реального вреда), либо на любой случайный процесс в системе (потенциально фатальный).
CVn
1
@ MichaelKjörling, спасибо за отзыв. Я обновил свой ответ за тот же комментарий, который оставил ОП. Похоже, timeoutкоманда делает именно то, что ищет, ожидая, пока ОП ответит на мои комментарии.
slm
@slm timeoutдолжно быть решением, которое мне нужно. Я сейчас проверяю
Адам Рычковски,
4

Я нашел кое - что немного лучше, чем timeout: timelimit.

У этого есть несколько преимуществ; Во-первых, пользователь может вручную прервать выполнение, нажав «Ctrl + C».

timelimitПрограмма доступна в репозитории Debian.

Адам Рычковски
источник
1
Попытка понять разницу между ч / б и лимитом времени. Тайм-аут может быть остановлен с помощью Ctrl + C. Каковы другие преимущества?
SLM
Ну, мой тайм-аут не может. Я использую Mint 14 (на основе Ubuntu Quantal).
Адам Рычковски
3

Вы можете настроить время процессора и другие вещи ulimit, в частности время процессора:

$ ulimit -t 60      # limit to 60 seconds
$ program
RSFalcon7
источник
См. U & L Q & A: unix.stackexchange.com/a/4666/7453 . @Gilles дает хороший обзор использования ulimit для этой цели.
SLM
0

Bash использует переменную, которая называется $BASHPIDона может быть использована в такой ситуации, например:

#!/bin/bash
do_face() {
    local parent=$1
    echo $BASHPID > pid
    sleep 10
    echo "Killing parent $parent"
    kill $parent
}

ME=$BASHPID
eval $(echo "do_face $ME &")
sleep 20 && kill $(cat pid) && echo "killed child $(cat pid)"
exit 1

Вы можете изменить аргумент в вызове sleepв do_face()к 100а 10и посмотреть , что происходит , когда ребенок занимает слишком много времени , чтобы сделать его работу по дому. Просто измените вызов в режим ожидания do_face()на вызов вашего исполняемого файла, и если это займет слишком много времени, сценарий убьет его, 20в этом примере значение является ограничивающим. Параметры могут быть реализованы так, что это становится простым сценарием для вызова и может быть вызван другим сценарием в пакетном режиме или как угодно. Обработка pid-файлов для каждого параллельного процесса - это проблема, которую нужно будет решить, возможно, используйте разные подкаталоги ...

NB. В GNU Linux sleepможет принимать аргументы с плавающей запятой, например, sleep 0.1спать в течение одной десятой секунды.

Overloaded_Operator
источник