Рекурсия в потоке - PullRequest
       1

Рекурсия в потоке

0 голосов
/ 16 февраля 2011

Это хорошая идея для вызова рекурсивной функции внутри потока? Я создаю 10 потоков, функция потока в свою очередь вызывает рекурсивную функцию. Плохая часть

ThreadFunc( )
{
   for( ;condn   ;   )
     recursiveFunc(objectId);
}


bool recursiveFunc(objectId)
{
    //Get a instance  to the database connection

    // Query for attibutes of this objectId

    if ( attibutes satisfy some condition)
        return true;
    else
        recursiveFunc(objectId)   // thats the next level of objectId
}

Рекурсивная функция имеет несколько обращений к базе данных. Я предполагаю, что вызов рекурсивной функции внутри цикла вызывает снижение производительности. Кто-нибудь может подтвердить

Ответы [ 4 ]

2 голосов
/ 16 февраля 2011

Вызов функции рекурсивно внутри потока сам по себе неплохая идея. Единственное, о чем вы должны знать, это ограничить глубину рекурсии, иначе вы можете вызвать (подождать ...) переполнение стека. Это не относится к многопоточности, но применимо в любом случае, когда вы используете рекурсию.

В этом случае я бы рекомендовал против рекурсии, потому что в этом нет необходимости. Ваш код является примером хвостовой рекурсии , которую всегда можно заменить циклом. Это устраняет проблему переполнения стека:

bool recursiveFunc(objectId)
{
    do
    {
        // Get an instance to the database connection

        // Query for attributes of this objectId

        // Update objectId if necessary (not sure what the "next level of objectId" is)
    }
    while(! attributes satisfy some condition);

    return true;
}
1 голос
/ 16 февраля 2011

Нет технической причины, по которой это не сработает - это совершенно законно.

Почему этот код является "плохой частью"?

Вам нужно будет отладить / профилировать это и recursiveFunc, чтобы увидеть, где происходит снижение производительности.

Исходя из кода, который вы разместили, вы проверили, что condn когда-либо удовлетворен, и ваш цикл завершается. Если нет, то он зациклится навсегда.

И что на самом деле делает recursiveFunc

UPDATE

Исходя из вашего комментария о том, что каждый поток выполняет 15 000 итераций, первым делом я бы переместил Get an instance to the database connection код за пределы recursiveFunc, чтобы вы получали его только один раз для каждого потока.

Даже если вы переписываете в цикл (согласно ответу Мартина Б.), вы все равно захотите это сделать.

0 голосов
/ 16 февраля 2011

Единственная потенциальная проблема, которую я вижу с размещенным кодом, состоит в том, что он может представлять бесконечный цикл, и это обычно не то, что вам нужно (поэтому вам придется принудительно разрывать где-то в известных достижимых условиях, чтобы избежать выхода из приложения чтобы вырваться из нити (а потом и нити).

Причиной снижения производительности может быть как многопоточность, так и рекурсия и доступ к базе данных по разным причинам. То, виноваты ли какие-либо из них или все они в ваших проблемах, невозможно определить по тому немногому, что вы нам показываете.

0 голосов
/ 16 февраля 2011

Зависит от того, как рекурсивная функция общается с базой данных. Если каждый (или много) уровень рекурсии повторно открывает базу данных, это может быть причиной деградации. Если они все используют одно и то же «соединение» с базой данных, проблема не в рекурсии, а в количестве потоков, одновременно обращающихся к базе данных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...