Как запустить программу на указанное количество времени? - PullRequest
4 голосов
/ 11 февраля 2012

Для задачи, требующей большого объема вычислений, я хочу ограничить время, затрачиваемое программой на процессор: если программа не находит решения в течение заданного времени, я хочу, чтобы программа была завершена. Вместо того, чтобы программа искала решение навсегда, оно должно завершиться, если ничего не найдено. В случае, если платформа имеет значение, это для UNIX. Как этого достичь?

Ответы [ 2 ]

9 голосов
/ 11 февраля 2012

Другое POSIX-решение, которое является однопоточным и автономным, заключается в использовании сигналов:

#include <unistd.h>
#include <csignal>

std::sig_atomic_t volatile done = 0;

void game_over(int) { done = 1; }

int main()
{
    std::signal(SIGALRM, game_over);
    alarm(5); // this program will self-destruct in 5 seconds

    while (!done)
    {
        do_my_thing();  // or whatever; make sure this returns frequently
    }
}

(Это одно из очень немногих законных и важных применений volatile: мы должны запретить компиляторуот оптимизации условного выражения while (!done), и компилятор не видит, что done может быть изменен, потому что он никогда не затрагивается внутри тела цикла.)

POSIX не рекомендует использовать std::signal в пользусвоего, более мощного sigaction.Обратитесь к руководству, если вам интересно, но для простой цели подачи сигнала тревоги этого решения, по-видимому, достаточно.

Если ваша программа не предлагает вообще никаких точек прерывания (то есть точек, в которых вы можете проверить done), то вы также можете вызвать abort() в обработчике сигнала.

5 голосов
/ 11 февраля 2012

Возможный подход - установить ограничение процесса на желаемое время.Ограничения UNIX, установленные с setrlimit(), соблюдаются средой выполнения и поддерживают как мягкое, так и жесткое ограничение.Когда мягкий предел достигнут, запускается сигнал, который можно использовать, например, для установки флага, указывающего, что программа должна завершиться.Когда жесткий предел достигнут, программу следует прекратить (хотя, похоже, это не работает на MacOS).Вот простой пример программы:

#include <sys/resource.h>
#include <iostream>
#include <signal.h>

sig_atomic_t finished = false;
void limit(int)
{
    finished = true;
}

int main()
{
    signal(SIGXCPU, limit);
    struct rlimit limit;
    limit.rlim_cur = 2;
    limit.rlim_max = 3;
    setrlimit(RLIMIT_CPU, &limit);

    unsigned long long i(0);
    while (++i && !finished)
    {
    }
    std::cout << "i=" << i << " flag=" << std::boolalpha << bool(finished) << "\n";
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...