Как завершить рекурсивную функцию через определенное время?

0

У меня есть рекурсивная функция в C++, и мне нужно немедленно завершить функцию, включая все вызовы, которые рекурсивно создаются через определенное время, например, 60 секунд. Я пробовал следующее, но не работает. takeTooLong - глобальная переменная, но если ее значение изменяется на 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);
        }
    }   
}
  • 3
    Если у вас есть вопрос по поводу вашего кода, было бы полезно, если бы вы разместили код здесь, чтобы мы могли его увидеть. "Есть идеи?" слишком расплывчато
  • 3
    Сделайте начальное время параметром, а время - частью логики рекурсии. Он не прекратит все вызовы сразу, поскольку стек рекурсивных вызовов необходимо «развернуть», но он достаточно близок.
Показать ещё 7 комментариев
Теги:
recursion

3 ответа

0

Самый простой способ выйти из неизвестного числа рекурсий - это выбросить исключение. Поскольку вы делаете это не чаще одного раза в 60 секунд, это не так уж плохо. Просто сделайте его class TimeLimitExceeded: public std::runtime_error и поймайте его в обертке верхнего уровня.

† Большинство рекурсивных функций не следует вызывать напрямую, а через нерекурсивную оболочку. Подпись рекурсивной функции обычно неудобна для вызывающих, поскольку она содержит детали реализации, которые не имеют отношения к вызывающему.

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);
}  
  • 0
    Такое прекращение может быть не самым быстрым способом. Предположим, ваша рекурсивная функция идет очень глубоко. Когда функция возвращается на уровне, мы должны ждать, чтобы все вызовы предка также вернулись . Теперь предположим, что на каждом уровне рекурсии n вызовов помещаются в стек. Это может сделать огромное количество предков.
  • 0
    Почему вы использовали вторую рекурсивную функцию?
Показать ещё 2 комментария
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;

    //........
}

Ещё вопросы

Сообщество Overcoder
Наверх
Меню