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

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

Страниц: [1] 2 3   Вниз
  Печать  
Автор Тема: Многопоточный сервер, нужно мнение по поводу кол-ва потоков.  (Прочитано 13339 раз)
Antiglobalist
Гость
« : Сентябрь 11, 2012, 01:47 »

Собственно есть сервер с подключенными к нему клиентами.
Главный поток получает данные от клиента, создает новый поток  и передает ему полученные данные.
В этом потоке идет обращение к бд  и ,как один из вариантов , создание xml'ки, после чего он уничтожается.

Вопрос: Оставить в таком виде или лучше создать N потоков , которые работают постоянно и отсылать им в  очередь данные для обработки ?
Записан
Bepec
Гость
« Ответ #1 : Сентябрь 11, 2012, 06:52 »

Представим 1000000 клиентов обратились одновременно, создалось 1000000 потоков, это хорошо? Веселый
Помоему выглядит как сбербанк с численностью сотрудников, равной количеству жителей России Веселый

PS я за очереди.
Записан
V1KT0P
Гость
« Ответ #2 : Сентябрь 11, 2012, 07:00 »

Собственно есть сервер с подключенными к нему клиентами.
Главный поток получает данные от клиента, создает новый поток  и передает ему полученные данные.
В этом потоке идет обращение к бд  и ,как один из вариантов , создание xml'ки, после чего он уничтожается.

Вопрос: Оставить в таком виде или лучше создать N потоков , которые работают постоянно и отсылать им в  очередь данные для обработки ?

Если кратко, то сколько ядер столько и потоков. Ибо одновременно будут работать только по одному потоку на ядро.
А так надо смотреть нюансы, например если у тебя 4 ядра и 4 потока и в какой-то момент начнутся выполняться 4 не приоритетные труднозатратные задачи. То может так получиться что более приоритетные задачи будут вынужденны непозволительно долго ожидать. Решений масса, все зависит от специфики задачи.
« Последнее редактирование: Сентябрь 11, 2012, 08:41 от V1KT0P » Записан
xokc
Птица говорун
*****
Offline Offline

Сообщений: 976



Просмотр профиля
« Ответ #3 : Сентябрь 11, 2012, 08:17 »

Если всё работает и проблем никаких уже сейчас нет - оставить как есть. Если проблемы уже есть или намечаются: ты и сам знаешь что делать - пул потоков тебе в руки. Оптимальное количество потоков можно получить через QThread::idealThreadCount().
Записан
Antiglobalist
Гость
« Ответ #4 : Сентябрь 11, 2012, 09:54 »

Всем спасибо за ответы )

Потоков уже 2 , комп 2 ядра. Сервер планирую под мобильные клиенты. Просто задумался на счет того сколько ресурсов тратится на создание и удаление потока.

Тут еще заметил одну странность:
В новом потоке , после обработки данных вызываются два сигнала
Код:
emit sendResult(resultCode,resultData);
        emit finish();
Первый соединен с объектом из начального потока, второй с this.
Код:
void Thread::startProcessing(quint16 recCode,QString recData){
    data=recData;
    code=recCode;
    std::cout <<  "33 ";
    connect(this,SIGNAL(finish()),SLOT(deleteThread()));
    start();
}
void Thread::deleteThread(){
    std::cout <<  "44 ";
    quit();
    wait();
    deleteLater();
}

Так создаю поток А:
Код:
QThread *thread = new QThread(this);
    connect(thread,SIGNAL(finished()),thread,SLOT(deleteLater()));
    pRecip->moveToThread(thread);
    thread->start()

Так Bn
Код:
Thread *newThread=new Thread();
    connect(newThread,SIGNAL(sendResult(quint16,QStringList)),client,SLOT(readResult(quint16,QStringList)));
    connect(this,SIGNAL(startProcessingThread(quint16,QString)),newThread,SLOT(startProcessing(quint16,QString)));
    emit startProcessingThread(code,data);
Происходит следующее- поток Bn отправляет сигнал , слот клиента(readResult) принимает , обрабатывает и вызывает свой сигнал на отправку данных клиенту , слот отправки отрабатывает и только после этого поток B удаляется. В чем косяк реализации ? Потоки Bn имеют свои обработчики(exec(); )
 
Смотрю много знающего народа на мой пост внимание обратило , поэтому можно еще вопрос-
Что бы отстраниться от Qt и писать клиента например на java , в приеме и отправке на серваке вместо QDataStream и QByteArray нужно использовать char *, я правильно понимаю ?
« Последнее редактирование: Сентябрь 11, 2012, 09:59 от Antiglobalist » Записан
xokc
Птица говорун
*****
Offline Offline

Сообщений: 976



Просмотр профиля
« Ответ #5 : Сентябрь 11, 2012, 10:01 »

Что бы отстраниться от Qt и писать клиента например на java , в приеме и отправке на серваке вместо QDataStream и QByteArray нужно использовать char *, я правильно понимаю ?
Я бы в качестве кроссязыковой прослойки использовал google protobuf.
Записан
Antiglobalist
Гость
« Ответ #6 : Сентябрь 11, 2012, 10:09 »

Что бы отстраниться от Qt и писать клиента например на java , в приеме и отправке на серваке вместо QDataStream и QByteArray нужно использовать char *, я правильно понимаю ?
Я бы в качестве кроссязыковой прослойки использовал google protobuf.

Спасибо, полезная вещь. Изучу
Записан
demaker
Птица говорун
*****
Offline Offline

Сообщений: 962


Просмотр профиля
« Ответ #7 : Сентябрь 11, 2012, 10:20 »

По Вашей задаче лучше создавать сервер и при  каждом  подключении создавать поток, а после отсоединения его удалять. Улыбающийся

QTcpServer::incomingConnection(int socketdescriptor)
{
  QThread*thread = new QThread(this,socketdescriptor)
 ...
}

ну и Потоке конектишься по дескриптеру.

Вот как-то так. Улыбающийся
Записан
Antiglobalist
Гость
« Ответ #8 : Сентябрь 11, 2012, 10:48 »

По Вашей задаче лучше создавать сервер и при  каждом  подключении создавать поток, а после отсоединения его удалять. Улыбающийся

QTcpServer::incomingConnection(int socketdescriptor)
{
  QThread*thread = new QThread(this,socketdescriptor)
 ...
}

ну и Потоке конектишься по дескриптеру.

Вот как-то так. Улыбающийся


Ну как мне кажется это не особо отличается от того , что у меня сейчас .
Код:
connect(this, SIGNAL(newClient(int)), pRecip, SLOT(newConnection(int)));
    QThread *thread = new QThread(this);
    connect(thread,SIGNAL(finished()),thread,SLOT(deleteLater()));
    pRecip->moveToThread(thread);
    thread->start();
Код:
void Server::incomingConnection(int socketDescriptor)
{
    //qDebug() << socketDescriptor << " Client Connected";
    emit newClient(socketDescriptor);
}
Всего лишь -1 поток будет в случае одновременной отправке клиентами запросов.
Но при этом Потоки висят до тех пор пока клиент не отсоединится и сокеты раскинуты по разным потокам.
« Последнее редактирование: Сентябрь 11, 2012, 10:51 от Antiglobalist » Записан
demaker
Птица говорун
*****
Offline Offline

Сообщений: 962


Просмотр профиля
« Ответ #9 : Сентябрь 11, 2012, 10:57 »

Ну да для каждого сокет свой поток и обмен данными.
А как должно быть по Вашему Шокированный
Записан
ecspertiza
Супер
******
Offline Offline

Сообщений: 1053


С уважением, мастер конфетного цеха!


Просмотр профиля
« Ответ #10 : Сентябрь 11, 2012, 11:28 »

Ну да для каждого сокет свой поток и обмен данными.
А как должно быть по Вашему Шокированный

а что будет при 1000 клиентах ?
Записан
demaker
Птица говорун
*****
Offline Offline

Сообщений: 962


Просмотр профиля
« Ответ #11 : Сентябрь 11, 2012, 11:35 »

Ну как надо делать Непонимающий тогда.
Записан
ecspertiza
Супер
******
Offline Offline

Сообщений: 1053


С уважением, мастер конфетного цеха!


Просмотр профиля
« Ответ #12 : Сентябрь 11, 2012, 11:56 »

собственно выше описали как делать, создавать количество потоков равное количеству ядер, и сокеты уже распределять по потокам. Как бы есть еще вариант например создавать на один поток 1000 соединений например. Но тут на форуме где то писали что первый вариант гораздо лучше, правда тему уже навряд ли найду.
Записан
demaker
Птица говорун
*****
Offline Offline

Сообщений: 962


Просмотр профиля
« Ответ #13 : Сентябрь 11, 2012, 13:41 »

 В замешательстве м-да интересно посмотреть на такой вариант было бы
Записан
xokc
Птица говорун
*****
Offline Offline

Сообщений: 976



Просмотр профиля
« Ответ #14 : Сентябрь 11, 2012, 13:48 »

А чего смотреть - брать любой готовый web сервер, например nginx, и смотреть как там сделано. А вообще, эта тема уже тут на форме раз 10 обсуждалась достаточно подробно, в том числе объяснялось, что использование Qt в качестве основы для ядра высоконагруженного сервера - это несколько неправильно, вследствие особенностей реализации QTcpSocket и относительной медлительности подсистемы сигнал/слот.
Записан
Страниц: [1] 2 3   Вверх
  Печать  
 
Перейти в:  


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