Ограничение времени работы программы в Linux - PullRequest
39 голосов
/ 05 марта 2010

В Linux я хотел бы запустить программу, но только в течение ограниченного времени, например, 1 секунды. Если программа превышает это время выполнения, я хотел бы завершить процесс и показать сообщение об ошибке.

Ответы [ 7 ]

101 голосов
/ 21 марта 2010

Ах, хорошо. timeout(1).

ОПИСАНИЕ
Запустите КОМАНДУ и убейте ее, если все еще работает после ДЛИТЕЛЬНОСТИ.

50 голосов
/ 05 марта 2010

StackOverflow не позволит мне удалить мой ответ, так как он принят. Он набирает отрицательные голоса, поскольку находится в верхней части списка, а под ним - лучшее решение. Если вы работаете в системе GNU, пожалуйста, используйте timeout вместо того, чтобы предлагать @wRAR. Итак, в надежде, что вы прекратите понижающее голосование, вот как это работает:

timeout 1s ./myProgram 

Вы можете использовать s, m, h или d для секунд (по умолчанию, если не указано), минут, часов или дней. Отличная особенность заключается в том, что вы можете указать другую опцию -k 30s (до 1s выше), чтобы убить ее с помощью SIGKILL через еще 30 секунд, если он не отвечает на исходный SIGTERM.

Очень полезный инструмент. Теперь прокрутите вниз и проголосуйте за ответ @ wRAR.


Для потомков это было мое оригинальное - низшее - предложение, оно все еще может быть, если кому-то пригодится.

Простой bash-скрипт должен сделать это за вас

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

Это должно сделать это.

$! расширяется до последнего фонового процесса (с помощью &), и kill возвращает false, если он не уничтожил какой-либо процесс, поэтому эхо выполняется только в том случае, если оно действительно что-то убило.

2>/dev/null перенаправляет kill stderr, в противном случае он напечатает что-то, сообщающее, что он не смог убить процесс.

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

EDIT
Как заметил Эфимент, здесь гонка, если ваша программа завершится, а какой-то другой процесс заберет pid, вместо этого он будет убит. Чтобы уменьшить вероятность этого, вы можете реагировать на SIGCHLD и не пытаться убить его, если это произойдет. Еще есть шанс убить неправильный процесс, но он очень далек.

trapped=""
trap 'trapped=yes' SIGCHLD
./myProgram &
sleep 1
[ -z "$trapped" ] && kill $! 2>/dev/null && echo '...'
21 голосов
/ 05 марта 2010

Может быть, ограничение времени процессора (ulimit -t / setrlimit(RLIMIT_CPU)) поможет?

3 голосов
/ 05 марта 2010

вы можете запустить его в сценарии оболочки, используя &

your_program &
pid=$!
sleep 1
if [ `pgrep $pid` ]
  then
    kill $pid
    echo "killed $pid because it took too long."
fi

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

1 голос
/ 18 декабря 2012
tail -f file & pid=$!
sleep 10
kill $pid 2>/dev/null && echo '...'
1 голос
/ 08 марта 2010

Хорошо, просто напишите короткую программу на C, которая fork s, вызывает execlp или что-то подобное в дочернем элементе, измеряет время в родительском элементе и kill s в дочернем Должно быть легко ...

0 голосов
/ 05 марта 2010

Если у вас есть источники, вы можете fork() в начале main(), а затем сделать так, чтобы родительский процесс измерил время и, возможно, уничтожил дочерний процесс.Просто используйте стандартные системные вызовы fork(), waitpid(), kill(), ... возможно, некоторую стандартную обработку сигналов Unix.Не слишком сложно, но требует некоторых усилий.

Вы также можете написать что-нибудь на оболочке, хотя я сомневаюсь, что это будет столь же точно относительно времени 1 секунды.измерьте время, наберите time <cmd ...> на оболочке.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...