QT SQLite и многопоточность |
Здравствуйте, гость ( Вход | Регистрация )
QT SQLite и многопоточность |
noneim |
8.6.2010, 14:22
Сообщение
#1
|
Новичок Группа: Новичок Сообщений: 1 Регистрация: 8.6.2010 Пользователь №: 1792 Спасибо сказали: 0 раз(а) Репутация: 0 |
На данный момент есть программа, использующая подключение к БД sqlite:
Инициализация:
Далее в разных потоках:
Но недавно прочитал , что оказывается так нельзя делать. Хотя вроде бы тестил и под windows и под Linux, работало без багов. Интересует надежность такого применения, на данных момент демон нормально держит uptime несколько дней, но вдруг возникнут какие-нибудь неожиданные баги? |
|
|
Kagami |
8.6.2010, 14:47
Сообщение
#2
|
Старейший участник Группа: Участник Сообщений: 601 Регистрация: 2.2.2009 Пользователь №: 523 Спасибо сказали: 101 раз(а) Репутация: 9 |
Ну, в принципе так делать можно. Просто SQLite может обрабатывать только один запрос на запись одновременно. Если в момент записи произойдет попытка еще одной записи в БД из другого потока, то этот второй поток просто будет заморожен пока первая операция записи не завершится.
|
|
|
512es |
1.12.2010, 4:38
Сообщение
#3
|
Участник Группа: Участник Сообщений: 135 Регистрация: 31.10.2008 Пользователь №: 407 Спасибо сказали: 5 раз(а) Репутация: 0 |
Недавно проводил стресс тесты. Методом экспериментов выяснил что работать с одним соединением в двух потоках лучше, чем с двумя отдельными. Хотя в доках по Qt написано что этого делать нельзя..
На деле разница получается в том что, когда одно соединение используется, второй поток блокируется. А если несколько соединений с одним файлом базы то второй поток иногда получает отказ в выполнении запроса. Постгрес в нескольких потоках вообще начинает страшно глючить, а склайт работает... А по теме советую всётаки вывести работу с базой в отдельный поток, ака db writer, и присылать в него данные через сигналы и слоты в режиме очереди. Тогда работать будет вообще идеально. Тем более, если вдруг база не успеет записать данные до получения новых, они просто выстроятся в очередь и запишутся чуть позже, ничего не теряя. |
|
|
Litkevich Yuriy |
6.12.2010, 21:56
Сообщение
#4
|
разработчик РЭА Группа: Сомодератор Сообщений: 9669 Регистрация: 9.1.2008 Из: Тюмень Пользователь №: 64 Спасибо сказали: 807 раз(а) Репутация: 94 |
|
|
|
512es |
7.12.2010, 9:12
Сообщение
#5
|
Участник Группа: Участник Сообщений: 135 Регистрация: 31.10.2008 Пользователь №: 407 Спасибо сказали: 5 раз(а) Репутация: 0 |
|
|
|
512es |
8.12.2010, 16:03
Сообщение
#6
|
Участник Группа: Участник Сообщений: 135 Регистрация: 31.10.2008 Пользователь №: 407 Спасибо сказали: 5 раз(а) Репутация: 0 |
тыкс.. кажется я придумал способ получше. точнее лишь более корректный, чем шарить соединение на 2 потока.
чтобы не получать ошибку о том что бд занята можно указать значение таймаунта побольше. db.setConnectOptions("QSQLITE_BUSY_TIMEOUT=10000"); правда не факт что подвисший поток всётаки разлочит базу и главный поток запишет данные |
|
|
FireBlack |
16.12.2014, 7:12
Сообщение
#7
|
Студент Группа: Участник Сообщений: 38 Регистрация: 17.10.2010 Из: г.Пенза Пользователь №: 2121 Спасибо сказали: 13 раз(а) Репутация: 1 |
Недавно споткнулся о грабли многопоточности и QSQLite. Сначала не обратил внимание на документацию и использовал одно подключение QSqlDatabase в нескольких потоках. В результате приложение падало с "unhandled exception" то в qsqlite.dll, то в ntdll.dll. Причем могло упасть как через 10 минут стресс-теста, так и через 2 часа.
Проблему решил с помощью QSqlDatabase::cloneDatabase, выдавая каждому потоку свое подключение к базе. Чтобы избежать ошибки "database is locked" работу с SQL обвернул в мьютекс. |
|
|
Текстовая версия | Сейчас: 28.11.2024, 18:56 |