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