对于计算密集型问题,我想限制程序花费的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
}
}
Run Code Online (Sandbox Code Playgroud)
(这是极少数合法且至关重要的用途之一volatile:我们必须阻止编译器优化while (!done)条件,并且编译器看不到它done可以被改变,因为它从未被触及循环体内.)
POSIX不鼓励使用std::signal自己的,更强大的sigaction.如果您有兴趣,请参阅手册,但出于报警的简单目的,此解决方案似乎就足够了.
如果您的程序根本没有提供中断点(即您可以检查的点done),那么您也可以调用abort()信号处理程序.
一种可能的方法是设置所需时间的过程限制.设置的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)