我在C ++中有一个递归函数,我需要立即终止函数,包括在特定时间后递归发出的所有调用,比如60秒。 我尝试了以下但不起作用。 takesTooLong是一个全局变量,但如果它的值在一次调用中变为1,则其他调用会将其视为0。 操作系统 Ubuntu 12.10 。
main()是这样的:
int main()
{
takesTooLong = 0;
startTime = clock();
RecursiveFunction();
endTime = clock();
printf("Elapsed time: %f", CalculateElapsedTime(startTime, endTime));
return 0;
}
我的递归函数:
void RecursiveFunction(Some Parameters)
{
if (takesTooLong == 1)
return;
endTime = clock();
differenceTime = CalculateElapsedTime(startTime, endTime);
if (differenceTime > MAX_SECONDS)
{
takesTooLong = 1;
}
if (takesTooLong == 0)
{
for (i = 0; i < n && takesTooLong == 0; i++)
{
RecursiveFunction(Some Updated Parameters);
}
}
}
答案 0 :(得分:0)
伪代码:
typedef ??? Time;//time type
Time getCurrentTime(); //returns time. Or ticks. Anything you could use to measure time.
void recursiveFunction(Time startTime){
...//do something here
Time currentTime = getCurrentTime();
if ((currentTime - startTime) > limit)
return;
recursiveFunction(startTime);
}
void recursiveFunction(){
Time startTime = getCurrentTime();
recursiveFunction(startTime);
}
答案 1 :(得分:0)
是的,你仍然必须展开堆栈,但替代方案都很难看,最好的可能是longjmp。如果您需要更高的分辨率而不是秒,或者您想测量进程/内核时间而不是挂钟时间,请使用timer_create
或setitimer
等替代方案。
void alarmHandler (int sig)
{
timedOut = 1;
}
signal(SIGALRM, alarmHandler);
alarm(60);
RecursiveFunction();
alarm(0);
if (timedOut)
{
//report something
timedOut = 0;
}
void RecursiveFunction(Some Parameters)
{
if (timedOut)
return;
//........
}
答案 2 :(得分:0)
退出未知数量的递归的最简单方法是抛出异常。由于你每60秒最多做一次,所以这并不算太糟糕。只需将其设为class TimeLimitExceeded : public std::runtime_error
并在顶级包装器中捕获†。
†大多数递归函数不应该直接调用,而是通过非递归包装器调用。递归函数的签名通常对于调用者来说是不方便的,因为它包含与调用者无关的实现细节。