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

How to run a program for a specified amount of time?

本文关键字:时间 运行 程序      更新时间:2023-10-16

对于计算密集型问题,我想限制程序花费的CPU时间:如果程序在给定的时间内找不到解决方案,我希望程序终止。与其让程序永远寻找解决方案,不如在一无所获的情况下终止。如果平台有问题,这是针对UNIX的。如何做到这一点?

另一个单线程且自包含的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()

一种可能的方法是设置所需时间的进程限制。使用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";
}