Многопоточный сбой SQLite - PullRequest
4 голосов
/ 21 января 2012

Я пытаюсь использовать SQLite 3.7.5 в многопоточной программе на C ++.Я сузил его до нескольких простых строк кода:

sqlite3 *Database;
sqlite3_stmt *Stmt;

int retval=sqlite3_open("database.db3",&Database);
retVal=sqlite3_prepare(&Database,"CREATE TABLE RawData (Key CHAR(5))",-1,&Stmt,0);
retval=sqlite3_step(Stmt);
retval=sqlite3_finalize(Stmt);

Когда я вызываю этот код прямо из моего основного процесса, он отлично работает.Однако, если я использую CreateThread () для создания потока:

unsigned long ThreadId;
CreateThread(0,0,(LPTHREAD_START_ROUTINE) InserterThread,&Info,0,&ThreadId);

, я получаю сообщение «переполнение буфера» Visual Studio при вызове sqlite3_step .Если я отлаживаю, я вижу, что место сбоя находится в _CRT_DEBUGGER_HOOK в dbghook.c.

Я использую многопоточные библиотеки Static VC и компилирую с определениями:

SQLITE_THREADSAFE=2
THREADSAFE=2

Я подтвердил с помощью sqlite3_threadsafe () .

Я могу немного проследить код SQLite 3, но я надеюсь, что кто-нибудь обнаружит очевидную проблему с моим кодом и спасет меняагрегация.

1 Ответ

3 голосов
/ 21 января 2012

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

Вам все еще нужно сообщить sqlite, что вы хотите многопоточное поведение, либопри запуске базы данных или во время выполнения.

Выбор режима потоков при запуске

Если предположить, что режим потоков во время компиляции не однопоточный, то режим потоковможет быть изменено во время инициализации с использованием интерфейса sqlite3_config ().Глагол SQLITE_CONFIG_SINGLETHREAD переводит SQLite в однопоточный режим, глагол SQLITE_CONFIG_MULTITHREAD устанавливает многопоточный режим, а глагол SQLITE_CONFIG_SERIALIZED устанавливает сериализованный режим.

Выбор режима многопоточности во время выполнения

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

Режим потоков для отдельного соединения с базой данных определяется флагами, заданными в качестве третьего аргумента для sqlite3_open_v2().Флаг SQLITE_OPEN_NOMUTEX приводит к тому, что соединение с базой данных находится в многопоточном режиме, а флаг SQLITE_OPEN_FULLMUTEX заставляет соединение находиться в сериализованном режиме.Если ни один из флагов не указан или если вместо sqlite3_open_v2 () используются sqlite3_open () или sqlite3_open16 (), то используется режим по умолчанию, определяемый настройками времени компиляции и запуска.

Ссылкаот http://www.sqlite.org/threadsafe.html

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