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

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

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: БД и многопоточность  (Прочитано 16971 раз)
demiurg
Гость
« : Сентябрь 18, 2011, 16:00 »

Незнаю где тему создать толи в БД толи в многопоточных приложениях .  Улыбающийся

Хочу в многопоточном TCP сервере подключаться к БД(MySQL)  и сохранять данные от клиентов в неё.  Появились вопросы по реализации такой структуры
1) Насколько я понял нужно создавать отдельное подключение в каждом потоке ?
2) Нужно ли именовать это подключение или же оно проименуюется по дефолту  и одинаковые имена не вызовут ошибку из разных потоков?
3) Нужно ли блокировать как то БД? Или же пересечение данных из разных подключений исключается?
Ну и чтобы не создавать ещё одну тему в другом разделе такой вопрос :
Т.к. приложение ответственно по времени , а каждый клиент при подключении выдаёт данных не более 20 Кб и по времени не более нескольких секунд - решил выделить каждому клиенту по потоку( вопреки общественному мнениею  Смеющийся ) . Вопрос - а какой максимальное кол-во потоков выдержит сервер на WinServer2003? Т.е. сотню например он выдержит?

Записан
LisandreL
Птица говорун
*****
Offline Offline

Сообщений: 984


Надо улыбаться


Просмотр профиля
« Ответ #1 : Сентябрь 18, 2011, 17:09 »

1) Да.
2) Нужно уникальное имя (я включал в имя адрес потока).
3) Зависит от логики работы. Атомарные изменения нужно заключать в транзакциях.
Возможно есть ещё ограничения в зависимости от системы хранения (MyISAM, InnoDB …) - точно не скажу.
4) Даже на не серверной винде приложение может запустить 800+ потоков.
Общественное мнение не потому рекомендует не делать слишком много потоков, что ОС их не выдержит, а потому, что так вы будете терять много времени на переключение между потоками и «ответственного по времени» будет в итоге тратиться больше.
Записан
demiurg
Гость
« Ответ #2 : Сентябрь 18, 2011, 18:01 »

1) Да.
2) Нужно уникальное имя (я включал в имя адрес потока).
3) Зависит от логики работы. Атомарные изменения нужно заключать в транзакциях.
Возможно есть ещё ограничения в зависимости от системы хранения (MyISAM, InnoDB …) - точно не скажу.
4) Даже на не серверной винде приложение может запустить 800+ потоков.
Общественное мнение не потому рекомендует не делать слишком много потоков, что ОС их не выдержит, а потому, что так вы будете терять много времени на переключение между потоками и «ответственного по времени» будет в итоге тратиться больше.

3) Логика простая - пришли данные, считался идентификатор,  и занеслись в таблицу с заполением поля соответствующему идентификатору. Отключение от сервера.
4)  Понятно , спасибо за разъяснения. Думаю не критично когда время передачи и обработки -  секунды а данных и 20Кб не наберётся.  

Цитировать
Возможно есть ещё ограничения в зависимости от системы хранения (MyISAM, InnoDB …) - точно не скажу.

Вот это интересно, что лучше для таких задач. Нужно "загуглить"...

« Последнее редактирование: Сентябрь 18, 2011, 18:11 от demiurg » Записан
LisandreL
Птица говорун
*****
Offline Offline

Сообщений: 984


Надо улыбаться


Просмотр профиля
« Ответ #3 : Сентябрь 18, 2011, 19:51 »

Ах да, ещё учтите, что у MySQL есть ограничение на количество одновременных подключений (впрочем настраиваемое).
Записан
Whiplash
Гость
« Ответ #4 : Сентябрь 19, 2011, 08:24 »

На Хабре как-то была статья про многопоточное приложение на Qt работающее с БД через singleton-класс. Т.е. собсно подключение одно на все потоки, которое обеспечено синглтоном в отдельном потоке. Потоки посылают ему сигналы с запросами или с параметрами запросов, а поток подключения выполняет это на БД.
Записан
demiurg
Гость
« Ответ #5 : Сентябрь 19, 2011, 09:49 »

На Хабре как-то была статья про многопоточное приложение на Qt работающее с БД через singleton-класс. Т.е. собсно подключение одно на все потоки, которое обеспечено синглтоном в отдельном потоке. Потоки посылают ему сигналы с запросами или с параметрами запросов, а поток подключения выполняет это на БД.
ууу, чо так сложно, я есчо не вырос до этого уровня. Да и если подключение одно - смысл многопоточности теряется. БД то может и  100 и 200 подключений выдерживать.  А если "зависнет" поток - то основное приложение не встанет( по идее).
Записан
Странник
Гость
« Ответ #6 : Сентябрь 19, 2011, 09:59 »

Да и если подключение одно - смысл многопоточности теряется. БД то может и  100 и 200 подключений выдерживать.  А если "зависнет" поток - то основное приложение не встанет( по идее).
и почему же теряется смысл, любопытно? запросы клиентов по-прежнему обрабатываются параллельно, а запись данных в БД последовательная в любом случае. но при одном подключении вы избавляетесь от накладных расходов на подключение-отключение клиентов к БД.
Записан
demiurg
Гость
« Ответ #7 : Сентябрь 19, 2011, 11:24 »

Да и если подключение одно - смысл многопоточности теряется. БД то может и  100 и 200 подключений выдерживать.  А если "зависнет" поток - то основное приложение не встанет( по идее).
и почему же теряется смысл, любопытно? запросы клиентов по-прежнему обрабатываются параллельно, а запись данных в БД последовательная в любом случае. но при одном подключении вы избавляетесь от накладных расходов на подключение-отключение клиентов к БД.

Да, не подумал, токма всёравно без примера не смогу реализовать  Обеспокоенный  У мну есть готовый многопоточный сервер- с ним я разобрался , а как реализовать этот singleton - чтото из разряда магии  Смеющийся
Записан
Странник
Гость
« Ответ #8 : Сентябрь 19, 2011, 11:38 »

да вот собственно упомянутая выше статься с Хабра, подробно и с примерами.
« Последнее редактирование: Сентябрь 19, 2011, 11:40 от Странник » Записан
demiurg
Гость
« Ответ #9 : Сентябрь 19, 2011, 11:46 »

Упс , да там не всё так сложно. Люблю примеры , надеюсь заработает  Улыбающийся (у меня  Смеющийся)  Спасибо  ,пойду шаманить ...
Записан
demiurg
Гость
« Ответ #10 : Сентябрь 19, 2011, 19:38 »

Цитировать
да вот собственно упомянутая выше статься с Хабра, подробно и с примерами.
Попытался скомпилить этот "синглетон", но на 
Код:
class DatabaseAccessor
 {
public:
     static DatabaseAccessor* getInstance();
     static QString dbHost;
     static QString dbName;
     static QString dbUser;
     static QString dbPass;

public slots:
     void executeSqlQuery(QString);
     void validateUser(QString, QString);

private:

     DatabaseAccessor();
     DatabaseAccessor(const DatabaseAccessor& );
     DatabaseAccessor& operator=(const DatabaseAccessor& );
     QSqlDatabase db;
 };
выдаёт Class declarations lacks Q_OBJECT macro.
 
а если добавить макросы Q-OBJECT - говорит что незнает что такое  dbHost;dbName;dbUser;dbPass;
Или это пример условно рабочий?
Записан
BRE
Гость
« Ответ #11 : Сентябрь 19, 2011, 19:42 »

Это же хабр. Улыбающийся
Что бы использовать сигналы/слоты класс должен быть наследником QObject и иметь макрос Q_OBJECT.
В таком виде "декларация слотов" как бы бесполезна.
Записан
demiurg
Гость
« Ответ #12 : Сентябрь 19, 2011, 19:50 »

Это же хабр. Улыбающийся
Что бы использовать сигналы/слоты класс должен быть наследником QObject и иметь макрос Q_OBJECT.
В таком виде "декларация слотов" как бы бесполезна.


Я это предвидел , поэтому написал так
Код:
class DatabaseAccessor:public QObject
 {
Q_OBJECT
public:
     static DatabaseAccessor* getInstance();
     static QString dbHost;
     static QString dbName;
     static QString dbUser;
     static QString dbPass;
private:

     DatabaseAccessor();
     DatabaseAccessor(const DatabaseAccessor& );
     DatabaseAccessor& operator=(const DatabaseAccessor& );
     QSqlDatabase db;
 };

Но тогда чёт вылазит ошибка вида
 undefined reference to `DatabaseAccessor::dbName' итд при попытке обращения.

Вроде ж явно объявлены. Ничо не понятно... ООП не моё  Обеспокоенный
Записан
BRE
Гость
« Ответ #13 : Сентябрь 19, 2011, 19:52 »

Статические переменные нужно определить в .cpp файле, у тебя они только декларированы.
В .cpp файле:
Код
C++ (Qt)
QString DatabaseAccessor::dbHost;
QString DatabaseAccessor::dbName;
...
 
Записан
demiurg
Гость
« Ответ #14 : Сентябрь 19, 2011, 20:35 »

Ну так я их и определял

так

Код:
DatabaseAccessor::DatabaseAccessor(QObject *parent)               
 {
     DatabaseAccessor::dbHost="localhost";
     db=QSqlDatabase::addDatabase("QMYSQL");
     db.setHostName(dbHost);
     db.setDatabaseName(dbName);
     db.setUserName(dbUser);
     db.setPassword(dbPass);
     if (db.open())
     {
         qDebug("connected to database");
     }
     else
     {
         qDebug("Error occured in connection to database");
     }
 }
пишет что уе задекларировано

и так
Код:
int main(int argc, char **argv) {
    QCoreApplication app(argc, argv);
    DatabaseAccessor::dbHost="localhost";
    DatabaseAccessor::getInstance();

Ниего не меняется.

Вообщем , чот сырец какой то, явно не моего уровня.
А где бы найти нормальное описание создания классов , только практически а не теория...
Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


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