Russian Qt Forum

Qt => Вопросы новичков => Тема начата: Antiglobalist от Сентябрь 11, 2012, 01:47



Название: Многопоточный сервер, нужно мнение по поводу кол-ва потоков.
Отправлено: Antiglobalist от Сентябрь 11, 2012, 01:47
Собственно есть сервер с подключенными к нему клиентами.
Главный поток получает данные от клиента, создает новый поток  и передает ему полученные данные.
В этом потоке идет обращение к бд  и ,как один из вариантов , создание xml'ки, после чего он уничтожается.

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


Название: Re: Многопоточный сервер, нужно мнение по поводу кол-ва потоков.
Отправлено: Bepec от Сентябрь 11, 2012, 06:52
Представим 1000000 клиентов обратились одновременно, создалось 1000000 потоков, это хорошо? :D
Помоему выглядит как сбербанк с численностью сотрудников, равной количеству жителей России :D

PS я за очереди.


Название: Re: Многопоточный сервер, нужно мнение по поводу кол-ва потоков.
Отправлено: V1KT0P от Сентябрь 11, 2012, 07:00
Собственно есть сервер с подключенными к нему клиентами.
Главный поток получает данные от клиента, создает новый поток  и передает ему полученные данные.
В этом потоке идет обращение к бд  и ,как один из вариантов , создание xml'ки, после чего он уничтожается.

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

Если кратко, то сколько ядер столько и потоков. Ибо одновременно будут работать только по одному потоку на ядро.
А так надо смотреть нюансы, например если у тебя 4 ядра и 4 потока и в какой-то момент начнутся выполняться 4 не приоритетные труднозатратные задачи. То может так получиться что более приоритетные задачи будут вынужденны непозволительно долго ожидать. Решений масса, все зависит от специфики задачи.


Название: Re: Многопоточный сервер, нужно мнение по поводу кол-ва потоков.
Отправлено: xokc от Сентябрь 11, 2012, 08:17
Если всё работает и проблем никаких уже сейчас нет - оставить как есть. Если проблемы уже есть или намечаются: ты и сам знаешь что делать - пул потоков тебе в руки. Оптимальное количество потоков можно получить через QThread::idealThreadCount().


Название: Re: Многопоточный сервер, нужно мнение по поводу кол-ва потоков.
Отправлено: Antiglobalist от Сентябрь 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 *, я правильно понимаю ?


Название: Re: Многопоточный сервер, нужно мнение по поводу кол-ва потоков.
Отправлено: xokc от Сентябрь 11, 2012, 10:01
Что бы отстраниться от Qt и писать клиента например на java , в приеме и отправке на серваке вместо QDataStream и QByteArray нужно использовать char *, я правильно понимаю ?
Я бы в качестве кроссязыковой прослойки использовал google protobuf.


Название: Re: Многопоточный сервер, нужно мнение по поводу кол-ва потоков.
Отправлено: Antiglobalist от Сентябрь 11, 2012, 10:09
Что бы отстраниться от Qt и писать клиента например на java , в приеме и отправке на серваке вместо QDataStream и QByteArray нужно использовать char *, я правильно понимаю ?
Я бы в качестве кроссязыковой прослойки использовал google protobuf.

Спасибо, полезная вещь. Изучу


Название: Re: Многопоточный сервер, нужно мнение по поводу кол-ва потоков.
Отправлено: demaker от Сентябрь 11, 2012, 10:20
По Вашей задаче лучше создавать сервер и при  каждом  подключении создавать поток, а после отсоединения его удалять. :)

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

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

Вот как-то так. :)


Название: Re: Многопоточный сервер, нужно мнение по поводу кол-ва потоков.
Отправлено: Antiglobalist от Сентябрь 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 поток будет в случае одновременной отправке клиентами запросов.
Но при этом Потоки висят до тех пор пока клиент не отсоединится и сокеты раскинуты по разным потокам.


Название: Re: Многопоточный сервер, нужно мнение по поводу кол-ва потоков.
Отправлено: demaker от Сентябрь 11, 2012, 10:57
Ну да для каждого сокет свой поток и обмен данными.
А как должно быть по Вашему :o


Название: Re: Многопоточный сервер, нужно мнение по поводу кол-ва потоков.
Отправлено: ecspertiza от Сентябрь 11, 2012, 11:28
Ну да для каждого сокет свой поток и обмен данными.
А как должно быть по Вашему :o

а что будет при 1000 клиентах ?


Название: Re: Многопоточный сервер, нужно мнение по поводу кол-ва потоков.
Отправлено: demaker от Сентябрь 11, 2012, 11:35
Ну как надо делать ??? тогда.


Название: Re: Многопоточный сервер, нужно мнение по поводу кол-ва потоков.
Отправлено: ecspertiza от Сентябрь 11, 2012, 11:56
собственно выше описали как делать, создавать количество потоков равное количеству ядер, и сокеты уже распределять по потокам. Как бы есть еще вариант например создавать на один поток 1000 соединений например. Но тут на форуме где то писали что первый вариант гораздо лучше, правда тему уже навряд ли найду.


Название: Re: Многопоточный сервер, нужно мнение по поводу кол-ва потоков.
Отправлено: demaker от Сентябрь 11, 2012, 13:41
 :-\ м-да интересно посмотреть на такой вариант было бы


Название: Re: Многопоточный сервер, нужно мнение по поводу кол-ва потоков.
Отправлено: xokc от Сентябрь 11, 2012, 13:48
А чего смотреть - брать любой готовый web сервер, например nginx, и смотреть как там сделано. А вообще, эта тема уже тут на форме раз 10 обсуждалась достаточно подробно, в том числе объяснялось, что использование Qt в качестве основы для ядра высоконагруженного сервера - это несколько неправильно, вследствие особенностей реализации QTcpSocket и относительной медлительности подсистемы сигнал/слот.


Название: Re: Многопоточный сервер, нужно мнение по поводу кол-ва потоков.
Отправлено: Antiglobalist от Сентябрь 11, 2012, 16:55
Про то что на Qt хороший серв не напишешь , это я читал , но так и не понял на чем было бы лучше , кто то говорит на чистых плюсах , другие на С , третьи вообще не знакомые мне языки или библиотеки называют)
Но я пишу для себя как курсовую , мне не слишком важна эффективность , но на будущее хотелось бы знать.


Название: Re: Многопоточный сервер, нужно мнение по поводу кол-ва потоков.
Отправлено: Alex Custov от Сентябрь 11, 2012, 16:56
на erlang или C


Название: Re: Многопоточный сервер, нужно мнение по поводу кол-ва потоков.
Отправлено: xokc от Сентябрь 11, 2012, 17:16
Мои личные предпочтения:
- Erlang;
- Node.js;
- C - libuv, libev, libevent
- C++: Zeroc ICE, asio
Для курсовика достаточно Qt будет.


Название: Re: Многопоточный сервер, нужно мнение по поводу кол-ва потоков.
Отправлено: ecspertiza от Сентябрь 11, 2012, 18:18
Где то читал что на java их еще пишут. Но как бы сам не особо в курсе, сам бы наверное писал на C++ и boost.


Название: Re: Многопоточный сервер, нужно мнение по поводу кол-ва потоков.
Отправлено: Igors от Сентябрь 11, 2012, 19:54
Думаю что главное "как писать" а не "на чем". Решение "один клиент - одна нитка" очевидно, как и его минусы. А иначе (по-взрослому) это такое же "разпоточивание" задачи, как и любой другой. Это имеет мало общего с обычным "многопоточным баловством", поэтому желающих не видно, и следующий спрашивает "ну как же правильно?" имея ввиду "ну где же взять готовое" - а его-то нет  :)


Название: Re: Многопоточный сервер, нужно мнение по поводу кол-ва потоков.
Отправлено: V1KT0P от Сентябрь 11, 2012, 20:20
Думаю что главное "как писать" а не "на чем". Решение "один клиент - одна нитка" очевидно, как и его минусы. А иначе (по-взрослому) это такое же "разпоточивание" задачи, как и любой другой. Это имеет мало общего с обычным "многопоточным баловством", поэтому желающих не видно, и следующий спрашивает "ну как же правильно?" имея ввиду "ну где же взять готовое" - а его-то нет  :)
Как по мне проще всего это дело делать на сигналах(не медленных как у Qt, а быстрых как у asio). Тогда просто создаешь несколько потоков и они вместе обслуживают всех клиентов. Плюс не надо морочить голову в какой поток пихать клиента.


Название: Re: Многопоточный сервер, нужно мнение по поводу кол-ва потоков.
Отправлено: demaker от Сентябрь 13, 2012, 09:01
Вообщем я понял что многопоточный сервак на Qt написать нельзя.
А тогда для чего все эти сигнало-слотовые соединения нужны,если они так медленно срабатывают ??? ??? ???


Название: Re: Многопоточный сервер, нужно мнение по поводу кол-ва потоков.
Отправлено: ecspertiza от Сентябрь 13, 2012, 09:27
Вообщем я понял что многопоточный сервак на Qt написать нельзя.

Можно :) но работать будет не так эффективно :)

А тогда для чего все эти сигнало-слотовые соединения нужны,если они так медленно срабатывают ??? ??? ???

Они работают не настолько медленно, они работают медленнее чем например бустовские сигнал\слоты или вызов по callback. Просто они не сильно хорошо подходят для высоко нагруженных серверов, где сигнало\слотовое соединения могут вызываться очень часто.


Название: Re: Многопоточный сервер, нужно мнение по поводу кол-ва потоков.
Отправлено: demaker от Сентябрь 13, 2012, 09:37
А тогда для чего все эти сигнало-слотовые соединения нужны,если они так медленно срабатывают ??? ??? ???

Они работают не настолько медленно, они работают медленнее чем например бустовские сигнал\слоты или вызов по callback. Просто они не сильно хорошо подходят для высоко нагруженных серверов, где сигнало\слотовое соединения могут вызываться очень часто.
[/quote]

По поводу callback функций. Ведь сигнало-слотовые соединения именно для и сделаны, чтобы отказаться от сallback функций.
А что чем чаще вызываются сигнало\слотовое соединения тем они медленее работают?


Название: Re: Многопоточный сервер, нужно мнение по поводу кол-ва потоков.
Отправлено: Serr500 от Сентябрь 13, 2012, 10:00
А что чем чаще вызываются сигнало\слотовое соединения тем они медленее работают?
Нет. Имеется в виду, что сигнал-слот жрёт больше процессорной мощности чем callback. Поэтому высоконагруженный сервис может просто "захлебнуться" - накладные расходы окажутся столь велики, что он не успеет обработать все сигналы. И тогда либо пропуск сигналов, либо "выедание" памяти для очереди сообщений и последующее падение.


Название: Re: Многопоточный сервер, нужно мнение по поводу кол-ва потоков.
Отправлено: demaker от Сентябрь 13, 2012, 11:13
Понятно :( И Qt c  этим никак не может совладать ???


Название: Re: Многопоточный сервер, нужно мнение по поводу кол-ва потоков.
Отправлено: demaker от Сентябрь 13, 2012, 11:15
Хотя даже у них в примерах есть написание многопоточного сервака.


Название: Re: Многопоточный сервер, нужно мнение по поводу кол-ва потоков.
Отправлено: Serr500 от Сентябрь 13, 2012, 11:18
Понятно :( И Qt c  этим никак не может совладать ???
Либо скорость, либо удобство...

Хотя даже у них в примерах есть написание многопоточного сервака.
Многопоточного, но не высоконагруженного.  :)


Название: Re: Многопоточный сервер, нужно мнение по поводу кол-ва потоков.
Отправлено: demaker от Сентябрь 13, 2012, 11:21
Ясно, спасибо Всем за разъяснения :)


Название: Re: Многопоточный сервер, нужно мнение по поводу кол-ва потоков.
Отправлено: demaker от Сентябрь 13, 2012, 11:24
Мои личные предпочтения:
- Erlang;
- Node.js;
- C - libuv, libev, libevent
- C++: Zeroc ICE, asio
Для курсовика достаточно Qt будет.

Извините, такой вопрос :)

А что значит для курсовика будет достаточно Qt?


Название: Re: Многопоточный сервер, нужно мнение по поводу кол-ва потоков.
Отправлено: Bepec от Сентябрь 13, 2012, 12:26
Курсовик представляет собой воображаемую программу, которая должна работать на бабочках и извергать из себя розовых пони :)

PS т.е. курсовик стремится к "работает и ладно", а программа серьёзная стремится к "чтоб работало быстрее/лучше/выше".


Название: Re: Многопоточный сервер, нужно мнение по поводу кол-ва потоков.
Отправлено: demaker от Сентябрь 13, 2012, 12:38
 ;D прошу прощение за глупый вопрос.