Russian Qt Forum
Ноябрь 24, 2024, 09:52 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Запросы к БД из трэда и зависание.  (Прочитано 6694 раз)
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


Жаждущий знаний


Просмотр профиля WWW
« : Ноябрь 17, 2008, 12:39 »

БД - постгрес. Вот трэд:
Код:
#ifndef QALARMCHECK_H
#define QALARMCHECK_H
//
#include <QThread>
#include "./../log.h"
class QAlarmCheck : public QThread
{
Q_OBJECT
private:
int iUID;
QLog* qlLog;
public:
QAlarmCheck(const int uid);
~QAlarmCheck();
protected:
void run();
};
#endif // QALARMCHECK_H

Код:
#include <QtGui>
#include <QtSql>
#include "qalarmcheck.h"
//
QAlarmCheck::QAlarmCheck(const int uid)
{
iUID=uid;
qlLog=new QLog();
}
//
QAlarmCheck::~QAlarmCheck()
{
delete qlLog;
}
//
void QAlarmCheck::run()
{
qlLog->message("QAlarmCheck","Start");
QSqlQuery* qsqQuery=new QSqlQuery(QSqlDatabase::database("QSZN"));
qsqQuery->prepare("SELECT count(*) FROM alarms_table "
"WHERE uid=:uid AND date=:date AND to_char(time,'HH24:MI')=:time");
//Set 1 second
this->sleep(60-QTime::currentTime().second()+1);
do
{
qsqQuery->bindValue(":uid",iUID);
qsqQuery->bindValue(":date",QDate::currentDate());
qsqQuery->bindValue(":time",QTime::currentTime().toString("hh:mm"));
if (qsqQuery->exec() && qsqQuery->next())
if (qsqQuery->value(0).toInt()>0)
{
qlLog->message("QAlarmCheck","Notify");
QSqlQuery* qsqQueryTmp=new QSqlQuery(QSqlDatabase::database("QSZN"));
qsqQueryTmp->exec("NOTIFY alarm");
delete qsqQueryTmp;
}
this->sleep(60);
}
while (this->isRunning());
delete qsqQuery;
qlLog->message("QAlarmCheck","Stop");
}
//
Это что-то типа крона, т.е. раз в минуту проверяет есть ли какое-либо напоминание на данную дату/время и если да, то создает NOTIFY. Запускаю я эту нить после запуска основного окна. Периодически в консоль вывалюваются вот такие сообщения:

Код:
message type 0x43 arrived from server while idle
message type 0x5a arrived from server while idle
message type 0x43 arrived from server while idle
message type 0x5a arrived from server while idle

И иногда, после таких вот сообщений, любое обращение к БД из основного окна приводит к зависанию.
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
Rcus
Гость
« Ответ #1 : Ноябрь 17, 2008, 13:41 »

"Иногда" в многопоточном приложении это конечно не смешно, вы как-нибудь контроллируете очередность использования подключения потоками?
Цитировать
Threads and the SQL Module

A connection can only be used from within the thread that created it. Moving connections between threads or creating queries from a different thread is not supported.

In addition, the third party libraries used by the QSqlDrivers can impose further restrictions on using the SQL Module in a multithreaded program. Consult the manual of your database client for more information
Записан
BRE
Гость
« Ответ #2 : Ноябрь 17, 2008, 13:46 »

Это цитата из документации http://www.crossplatform.ru/documentation/qtdoc4.3/threads.php
Цитировать
Потоки и модуль SQL
Соединение может использоваться только внутри создавшего его потока. Перемещение соединений между потоками и создание запросов в другой поток не поддерживается.
Кроме того, библиотеки третьих лиц, используемые драйверами QSqlDriver могут наложить дополнительные ограничения на использование Модуля SQL в многопоточной программе. За дополнительной информацией обращайтесь к создателю клиента базы данных.
Ты же пытаешься использовать соединение созданное в главном потоке, внутри своего потока.
Попробуй создавать еще одно соединение внутри своего потока и использовать его.
Записан
Rcus
Гость
« Ответ #3 : Ноябрь 17, 2008, 14:03 »

Ты же пытаешься использовать соединение созданное в главном потоке, внутри своего потока.
Попробуй создавать еще одно соединение внутри своего потока и использовать его.
Я как-то пытался использовать подобный подход (система плагинов, каждый плагин выполнялся в отдельном потоке и каждому нужно было общаться с базой). Но для каждого подключения постгрес создает отдельный процесс, что не слишком хорошо сказывается на потреблении памяти (если экземпляров приложения*потоков мало то можно забить).
В моей задаче проще оказалось использовать одно подключение, а потокобезопасность обеспечивать QMutex+QMutexLocker
Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


Жаждущий знаний


Просмотр профиля WWW
« Ответ #4 : Ноябрь 17, 2008, 18:11 »

Всем спасибо. Я с трэдами раньше не работал, поэтому так протупил. Теперь все нормально работает и не виснет (создаю подключение в потоке), но все таки в консоль периодически вываливается
message type 0x43 arrived from server while idle
message type 0x5a arrived from server while idle
message type 0x43 arrived from server while idle
message type 0x5a arrived from server while idle

Что бы это значило?
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
pastor
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 2901



Просмотр профиля WWW
« Ответ #5 : Ноябрь 17, 2008, 18:26 »

Что бы это значило?

Попробуй спросить у гугла. По это й проблеме много страниц
Записан

Integrated Computer Solutions, Inc. (ICS)
http://www.ics.com/
Kolobok
Гость
« Ответ #6 : Апрель 25, 2010, 16:26 »

У меня проблема противоположная. Я использую одно соединение в нескольких потоках и все работает стабильно. Прочитал в асистенте этот абзац и удивился. Что я делаю не так? База sqlite.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.051 секунд. Запросов: 23.