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

Die*_*ühl 4 c++ unix

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

Ker*_* SB 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
    }
}
Run Code Online (Sandbox Code Playgroud)

(这是极少数合法且至关重要的用途之一volatile:我们必须阻止编译器优化while (!done)条件,并且编译器看不到它done可以被改变,因为它从未被触及循环体内.)

POSIX不鼓励使用std::signal自己的,更强大的sigaction.如果您有兴趣,请参阅手册,但出于报警的简单目的,此解决方案似乎就足够了.

如果您的程序根本没有提供中断点(即您可以检查的点done),那么您也可以调用abort()信号处理程序.


Die*_*ühl 5

一种可能的方法是设置所需时间的过程限制.设置的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";
}
Run Code Online (Sandbox Code Playgroud)

  • 另请注意,您可以使用`ulimit -t`从命令行执行此操作. (2认同)
  • 我认为你只允许在信号处理程序中使用列入白名单的变量变异,而且我不确定列表中是否有`bool`.不过,`sig_atomic_t`似乎是为这个目的量身定做的. (2认同)