如何在指定的时间内运行程序?

时间:2012-02-11 12:11:43

标签: c++ unix

对于计算密集型问题,我想限制程序花费的CPU时间:如果程序在给定的时间内没有找到解决方案,我希望程序终止。而不是让程序永远寻找解决方案,它应该终止,如果没有找到。如果平台很重要,这适用于UNIX。如何实现这一目标?

2 个答案:

答案 0 :(得分:9)

另一种单线程和独立的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()

答案 1 :(得分:5)

可能的方法是设置所需时间的过程限制。运行时环境会观察到使用setrlimit()设置的UNIX限制,它们同时支持软限制和硬限制。当达到软限制时,触发信号,例如可以使用该信号。设置一个标志,指示程序应该结束。当达到硬限制时,程序应该终止(虽然这似乎不适用于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";
}