crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )


  Ответ в QT SQLite и многопоточность
Введите ваше имя
Подтвердите код

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

Опции сообщения
 Включить смайлы?
Иконки сообщения
(Опционально)
                                
                                
  [ Без иконки ]
 


Последние 10 сообщений [ в обратном порядке ]
FireBlack Дата 16.12.2014, 7:12
  Недавно споткнулся о грабли многопоточности и QSQLite. Сначала не обратил внимание на документацию и использовал одно подключение QSqlDatabase в нескольких потоках. В результате приложение падало с "unhandled exception" то в qsqlite.dll, то в ntdll.dll. Причем могло упасть как через 10 минут стресс-теста, так и через 2 часа.
Проблему решил с помощью QSqlDatabase::​cloneDatabase, выдавая каждому потоку свое подключение к базе. Чтобы избежать ошибки "database is locked" работу с SQL обвернул в мьютекс.
512es Дата 8.12.2010, 16:03
  тыкс.. кажется я придумал способ получше. точнее лишь более корректный, чем шарить соединение на 2 потока.

чтобы не получать ошибку о том что бд занята можно указать значение таймаунта побольше.

db.setConnectOptions("QSQLITE_BUSY_TIMEOUT=10000");


правда не факт что подвисший поток всётаки разлочит базу и главный поток запишет данные
512es Дата 7.12.2010, 9:12
 
Цитата(Litkevich Yuriy @ 6.12.2010, 21:56) *
чем лучше?

Лучше лишь тем, что все запросы выполнятся и ни разу не будет отказа database is locked. Вместо отказа просто поток подождёт освобождения бд.
Litkevich Yuriy Дата 6.12.2010, 21:56
 
Цитата(512es @ 1.12.2010, 6:38) *
Методом экспериментов выяснил что работать с одним соединением в двух потоках лучше
чем лучше?
Результаты тестов приведи и условия тестов
512es Дата 1.12.2010, 4:38
  Недавно проводил стресс тесты. Методом экспериментов выяснил что работать с одним соединением в двух потоках лучше, чем с двумя отдельными. Хотя в доках по Qt написано что этого делать нельзя..

На деле разница получается в том что, когда одно соединение используется, второй поток блокируется. А если несколько соединений с одним файлом базы то второй поток иногда получает отказ в выполнении запроса.

Постгрес в нескольких потоках вообще начинает страшно глючить, а склайт работает...


А по теме советую всётаки вывести работу с базой в отдельный поток, ака db writer, и присылать в него данные через сигналы и слоты в режиме очереди. Тогда работать будет вообще идеально.
Тем более, если вдруг база не успеет записать данные до получения новых, они просто выстроятся в очередь и запишутся чуть позже, ничего не теряя.
Kagami Дата 8.6.2010, 14:47
  Ну, в принципе так делать можно. Просто SQLite может обрабатывать только один запрос на запись одновременно. Если в момент записи произойдет попытка еще одной записи в БД из другого потока, то этот второй поток просто будет заморожен пока первая операция записи не завершится.
noneim Дата 8.6.2010, 14:22
  На данный момент есть программа, использующая подключение к БД sqlite:
Инициализация:
    db = QSqlDatabase::addDatabase("QSQLITE");
    db.setDatabaseName(path);
    if (!db.open())
    {
        return false;
    }


Далее в разных потоках:
    QSqlQuery query = QSqlQuery(db);
    query.prepare("INSERT INTO ip_list (ip, host, vps, assigned) "
                "VALUES (?, ?, ?, ?)");
        query.addBindValue(new_ip->ip);
        query.addBindValue(new_ip->host);
        query.addBindValue(new_ip->vps);
        query.addBindValue(new_ip->assigned);
        query.exec();


Но недавно прочитал , что оказывается так нельзя делать.
Хотя вроде бы тестил и под windows и под Linux, работало без багов.
Интересует надежность такого применения, на данных момент демон нормально держит uptime несколько дней, но вдруг возникнут какие-нибудь неожиданные баги?


Просмотр темы полностью (откроется в новом окне)
RSS Текстовая версия Сейчас: 29.3.2024, 5:24