SQLite3 пропускает дескрипторы в многопоточной среде

Я написал простую программу, которая порождает 10 потоков, каждый поток открывает базу данных (общую для всех потоков) или создает ее (с опцией «Write-Ahead Log»), если открыть не удается, создает таблицу в базе данных, а затем идет в бесконечный цикл, в котором он добавляет одну строку за раз в свою таблицу. Я обнаружил, что программа пропускает около 2 дескрипторов каждые 5 минут, я попробовал инструмент под названием Memory Verify, который сообщает мне, что утечка дескрипторов является блокировкой файлов SQLite3 (строка 34034 в версии 3.7.13), но я не уверен, что ошибка в SQLite или так, как я его использую.

Я не указал никакой опции компилятора для сборки SQLite3, поэтому он построен как многопоточный, и, насколько я понимаю, многопоточный режим должен работать нормально в моем случае, поскольку каждый поток имеет свое собственное соединение SQLite.

Для открытия или создания базы данных я использую следующий код:

   bool Create()
{
int iFlags = 0;
iFlags = iFlags | SQLITE_OPEN_READWRITE | SQLITE_OPEN_NOMUTEX | SQLITE_OPEN_CREATE;
return sqlite3_open_v2(dbName_sm.c_str(), &pHandle_m, iFlags, 0) == SQLITE_OK;
}

bool Open()
{
int iFlags = 0;
iFlags = iFlags | SQLITE_OPEN_READWRITE | SQLITE_OPEN_NOMUTEX;
return sqlite3_open_v2(dbName_sm.c_str(), &pHandle_m, iFlags, 0) == SQLITE_OK;
}

Жесткий цикл в каждом потоке вызывает ExecuteQuery, который подготавливает, выполняет шаг и завершает оператор INSERT:

   bool ExecuteQuery(const std::string& statement)
{
bool res = Prepare(statement);
if(!res)
{
return false;;
}
SQLiteStatus status = Step();
Finalize();
res = (ESuccess == status || EDatabaseDone == status);
return res;
}

bool Prepare(const std::string& statement)
{
return sqlite3_prepare_v2(pHandle_m, statement.c_str(), -1, &pStmt_m, 0) == SQLITE_OK;
}

enum SQLiteStatus { ESuccess, EDatabaseDone, EDatabaseTimeout, EDatabaseError };
SQLiteStatus Step()
{
int iRet = sqlite3_step(pStmt_m);
if (iRet == SQLITE_DONE)
{
return EDatabaseDone;
}
else if (iRet == SQLITE_BUSY)
{
return EDatabaseTimeout;
}
else if (iRet != SQLITE_ROW)
{
return EDatabaseError;
}
return ESuccess;
}

bool Finalize()
{
int iRet = sqlite3_finalize(pStmt_m);
pStmt_m = 0;
return iRet == SQLITE_OK;
}

Ребята, вы видите какую-то ошибку в моем коде или это известная проблема в SQLite? Я пытался гуглить пару дней, но ничего не нашел.

Большое спасибо за Вашу помощь.

С Уважением,

Andrea

Постскриптум Я забыл сказать, что я запускаю свой тест на 64-битном ПК с WinXP, компилятор VS2010, приложение скомпилировано в 32-битной версии SQLite 3.7.13 …

2

Решение

проверьте, есть ли у вас sqlite3_reset после каждого sqlite3_step, потому что это один случай, который может вызвать утечки. после подготовки оператора с помощью sqlite3_prepare и его выполнения с помощью sqlite3_step необходимо всегда сбрасывать его с помощью sqlite3_reset.

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]