Russian Qt Forum

Qt => Базы данных => Тема начата: Пантер от Ноябрь 17, 2008, 12:39



Название: Запросы к БД из трэда и зависание.
Отправлено: Пантер от Ноябрь 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

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


Название: Re: Запросы к БД из трэда и зависание.
Отправлено: Rcus от Ноябрь 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


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


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


Название: Re: Запросы к БД из трэда и зависание.
Отправлено: Пантер от Ноябрь 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

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


Название: Re: Запросы к БД из трэда и зависание.
Отправлено: pastor от Ноябрь 17, 2008, 18:26
Что бы это значило?

Попробуй спросить у гугла (http://www.google.ru/search?hl=ru&newwindow=1&as_qdr=all&q=message+type+arrived+from+server+while+idle&btnG=%D0%9F%D0%BE%D0%B8%D1%81%D0%BA&lr=&aq=f&oq=). По это й проблеме много страниц


Название: Re: Запросы к БД из трэда и зависание.
Отправлено: Kolobok от Апрель 25, 2010, 16:26
У меня проблема противоположная. Я использую одно соединение в нескольких потоках и все работает стабильно. Прочитал в асистенте этот абзац и удивился. Что я делаю не так? База sqlite.