Russian Qt Forum
Ноябрь 22, 2024, 16:05
Добро пожаловать,
Гость
. Пожалуйста,
войдите
или
зарегистрируйтесь
.
Вам не пришло
письмо с кодом активации?
1 час
1 день
1 неделя
1 месяц
Навсегда
Войти
Начало
Форум
WIKI (Вики)
FAQ
Помощь
Поиск
Войти
Регистрация
Russian Qt Forum
>
Forum
>
Qt
>
Многопоточное программирование, процессы
>
Как организовать многопоточность? Выбор модели
Страниц:
1
[
2
]
3
Вниз
« предыдущая тема
следующая тема »
Печать
Автор
Тема: Как организовать многопоточность? Выбор модели (Прочитано 21624 раз)
deMax
Хакер
Offline
Сообщений: 600
Re: Как организовать многопоточность? Выбор модели
«
Ответ #15 :
Октябрь 24, 2016, 09:54 »
Цитата: rudireg от Октябрь 24, 2016, 09:28
Выходит что на самом деле используется
2 потока
а не 50 в итоге...
Да хоть сто создайте, зачем только если вычислений с гулькин нос и все потоки простаивают, т.к. считать им нечего. У вас же не сотни тысяч клиентов. Как правило если тяжелые вычисления количество потоков =количеству ядер + по отдельному потоку на гуи/бд/файловую систему и прочие тормозные вещи.
Записан
Bepec
Гость
Re: Как организовать многопоточность? Выбор модели
«
Ответ #16 :
Октябрь 24, 2016, 10:01 »
Потоки эт как холопы.
Можно хоть тыщу нагнать, но если надо 2 кирпича с место на место переносить, то двое прекрасно справятся
Вот когда двое не будут справляться с нагрузкой - тогда надо добавлять.
Зависимость скорости работы от количества потоков непропорциональная и разнится от задачи к задаче. Но сейчас модно пихать многопоточность всюду, начиная от калькуляторов, заканчивая играми.
Записан
Igors
Джедай : наставник для всех
Offline
Сообщений: 11445
Re: Как организовать многопоточность? Выбор модели
«
Ответ #17 :
Октябрь 24, 2016, 13:31 »
Цитата: rudireg от Октябрь 24, 2016, 09:28
Выскажите ваше мнение... по поводу того, что в интернете очень часто можно встретить программы, в которых можно указать кол. потоков для работы.
Например вот
Ну это скорее "анти-пример"
Цитата: rudireg от Октябрь 24, 2016, 09:28
Я так понимаю что ОС не запускает на самом деле 50 потоков, а создает псевдо потоки.... (видимо они стоят в очереди на выполнение)
Нет, хоть с 1 ядром ОС честно запускает все 50 (или сколько сказали), каждому выделяется квант времени, гарантируется что нитка получит управление не позже чем <конкретное время>
Цитата: rudireg от Октябрь 24, 2016, 09:28
Почему именно этот метод получил такое широкое распространение в народе...
Просто потому что дятлов всегда больше чем умных
Оно ж ведь кажется очень удобным - эта нитка занимается одной задачей, другая другой.
Записан
rudireg
Гость
Re: Как организовать многопоточность? Выбор модели
«
Ответ #18 :
Октябрь 24, 2016, 17:48 »
1)
Правильно ли я понял тот факт, что запуская объект
obj
(наследник от
QRunnable
) на выполнение через
QThreadPool
,
то есть выполнив команду:
QThreadPool::globalInstance()->start(obj);
То метод
run()
объекта
obj
выполняется в отдельной нитке и при этом
не имеет цикла обработки событий
, иными словами
obj
завершает свою работу как только
void run()
выполнил последнюю команду.
2)
А если нужно что бы нитки не завершали свою работу а просматривали
очередь заданий
, и если там есть новые задания то брали их на выполнение, а если нет заданий то нитка засыпает на короткое время (sleep на 1 секунду) и после снова проверяет наличие новых заданий.
Цикл ожидания (сон, и проверка новых заданий) следует реализовать своими силами тогда... верно?
Например зациклить выполнение метода
run()
, и опрашивать раз в секунду есть ли новое задание на выполнение... если нету, то
QThread::sleep(1);
и снова проверить очередь.
ВОПРОС:
В правильном ли направлении я мыслю? что бы не вызывать каждый раз
QThreadPool::globalInstance()->tryStart(obj)
«
Последнее редактирование: Октябрь 24, 2016, 18:03 от rudireg
»
Записан
Old
Джедай : наставник для всех
Offline
Сообщений: 4350
Re: Как организовать многопоточность? Выбор модели
«
Ответ #19 :
Октябрь 24, 2016, 18:10 »
Цитата: rudireg от Октябрь 24, 2016, 17:48
1)
Правильно ли я понял тот факт.
Да
Цитата: rudireg от Октябрь 24, 2016, 17:48
2)
А если нужно что бы нитки не завершали свою работу а просматривали
очередь заданий
, и если там есть новые задания то брали их на выполнение, а если нет заданий то нитка засыпает на короткое время (sleep на 1 секунду) и после снова проверяет наличие новых заданий.
Не нужно так делать - это плохое решение. Для организации таких очередей нужно использовать условные переменные (QWaitCondition).
Цитата: rudireg от Октябрь 24, 2016, 17:48
Цикл ожидания (сон, и проверка новых заданий) следует реализовать своими силами тогда... верно?
Нет, это все уже реализовано в QThreadPool, попробуйте просто добавлять задачи через start, они ставятся в очередь и будут выполняться по мере освобождения воркеров.
Записан
Igors
Джедай : наставник для всех
Offline
Сообщений: 11445
Re: Как организовать многопоточность? Выбор модели
«
Ответ #20 :
Октябрь 25, 2016, 07:03 »
Цитата: rudireg от Октябрь 24, 2016, 17:48
То метод
run()
объекта
obj
выполняется в отдельной нитке и при этом
не имеет цикла обработки событий
,
Да
Цитата: rudireg от Октябрь 24, 2016, 17:48
иными словами
obj
завершает свою работу как только
void run()
выполнил последнюю команду.
Неясно что obj должен "завершать"
Цитата: rudireg от Октябрь 24, 2016, 17:48
2)
А если нужно что бы нитки не завершали свою работу а просматривали
очередь заданий
, и если там есть новые задания то брали их на выполнение, а если нет заданий то нитка засыпает на короткое время (sleep на 1 секунду) и после снова проверяет наличие новых заданий.
Рано или поздно все приходят к одному: sleep хорош для отладки, но НИКОГДА в рабочем коде
Цитата: rudireg от Октябрь 24, 2016, 17:48
Цикл ожидания (сон, и проверка новых заданий) следует реализовать своими силами тогда... верно?
Например зациклить выполнение метода
run()
, и опрашивать раз в секунду есть ли новое задание на выполнение... если нету, то
QThread::sleep(1);
и снова проверить очередь.
Это не запрещено, но зачем брать на себя низкоуровневую работу? Гораздо удобнее сидеть в QThread::exec и делать задание при получении сигнала
Цитата: rudireg от Октябрь 24, 2016, 17:48
ВОПРОС:
В правильном ли направлении я мыслю? что бы не вызывать каждый раз
QThreadPool::globalInstance()->tryStart(obj)
Не знаю. Ну а что такого уж плохого в QThreadPool и tryStart чтобы его избегать? Подбрасываете ему дровишки-задачки, оформить run несложно. Голова не болит какая нитка чем занимается. Минусы - пожалуй один, нельзя послать obj сигнал, он не в событийном цикле.
Записан
rudireg
Гость
Re: Как организовать многопоточность? Выбор модели
«
Ответ #21 :
Октябрь 25, 2016, 15:09 »
Спасибо вам
Old
и
Igors
Понемногу начинаю разбираться... делаю тесты и выяснил следующее
Методы запуска
start
и
tryStart
класса
QThreadPool
имеют различия:
QThreadPool::start();
- Запускает объект унаследованный от
QRunnable
на выполнение.
Если нет свободных зарезервированных ниток, то выполнение ставиться
в очередь
заданий.
QThreadPool::tryStart();
-
Пытается
запустить объект унаследованный от
QRunnable
на выполнение.
Если нет свободных зарезервированных ниток, то выполнение
НЕ ставиться
в очередь заданий, и запуск игнорируется.
И в свою очередь метод
QThreadPool::globalInstance()->waitForDone();
- Вызывает ожидание выполнения всех ниток,
а после удаляет объекты унаследованные от
QRunnable
, при условии что объект имеет статус
setAutoDelete(
true
)
«
Последнее редактирование: Октябрь 25, 2016, 15:12 от rudireg
»
Записан
popper
Гость
Re: Как организовать многопоточность? Выбор модели
«
Ответ #22 :
Октябрь 26, 2016, 18:00 »
Достаточно подробно про потоки в Qt написано здесь:
Mark Summerfield
Advanced Qt Programming
Записан
rudireg
Гость
Re: Как организовать многопоточность? Выбор модели
«
Ответ #23 :
Октябрь 27, 2016, 17:49 »
Возник вопрос.
Допустим задача программы это: отсылка сетевых запросов, получение ответа и их дальнейшая обработка (сохранение coockie, парсинг нужной информации... сохранение информации).
Сетевых запросов много... при этом
используются прокси
, прокси могут быть медленными... то есть ожидание ответа от сервера может ожидаться например
30 секунд
и более (если прокси медленный).
Если программа многопоточная, то поток получив задание сделать сетевой запрос делает следующее:
1)
Посылает запрос на сервер
2)
Ожидает ответ сервера
3)
Получает ответ сервера и обрабатывает его с последующим сохранением нужных данных
И если например таких запросов нужно отправить 1000 штук, а в микропроцессоре компьютера всего
4 ядра
,
то получается что в один момент времени программа может работать с максимум
4-мя
потоками.
Как можно оптимизировать механизм отправки и получения сетевых запросов?
ведь поток ожидая ответа (если прокси медленный).... простаивает.
Ранее я уже не один раз работал в программах с сетевыми запросами, и был написан класс по отправке и приему данных
видимо пришло время его переписать, так как поток будет ожидать ответа от сервера и простаивать...
На всякий случай выкладываю исходники класса по работе с HTTP запросами
rhttp.h
http://codepad.org/VszY9dsj
rhttp.cpp
http://codepad.org/c7fH60ui
На мой вгляд, следует отправлять запрос серверу... и на этом поток завершил свою задачу...
QNetworkReply *reply = this->manager->get(request);
Далее как то нужно сохранить данные об отправке, и на сигнале
finished
о том что ответ пришел, снова в потоке (в любом) уже принимать ответ от сервера.
QObject::connect(reply, SIGNAL(finished()), какойто объект, SLOT(Слот Обработки ответа сервера()));
Вопрос тока, кто будет этот сигнал посылать, если поток уже отработал и уничтожился, если тока как вариант сохранять reply в поток MANAGER (главный поток)
«
Последнее редактирование: Октябрь 27, 2016, 18:14 от rudireg
»
Записан
Bepec
Гость
Re: Как организовать многопоточность? Выбор модели
«
Ответ #24 :
Октябрь 27, 2016, 18:13 »
Вы НИЧЕРТА не понимаете что такое ядро, что такое поток и что такое ОС
Прошу вас - не придумывайте свои понятия.
Ядро - по сути процессор, выполняющий команды.
ОС - программа, позволяющая пользователю работать с компьютером.
Поток - это абстрактный список команд, имеющий право на часть процессорного времени.
Ядро - одно.
Ос - одна.
Потоков - сколько душе угодно. Правда есть предел потоков для ОС, но он чрезвычайно труднодостижим.
Количество потоков ни как не зависит от количества ядер.
Записан
Old
Джедай : наставник для всех
Offline
Сообщений: 4350
Re: Как организовать многопоточность? Выбор модели
«
Ответ #25 :
Октябрь 27, 2016, 18:36 »
Цитата: rudireg от Октябрь 27, 2016, 17:49
На мой вгляд, следует отправлять запрос серверу...
Не мудрите зря.
Пусть будет поток, который отправляет запросы и обрабатывает сигнал:
void QNetworkAccessManager::finished(QNetworkReply *reply)
Заметьте, это сигнал у самого менеждера и в параметре он передает указатель на reply.
Как только, ответ получен - он отправляется на обработку одному из воркеров пула потоков.
Одного потока-менеджера хватит и отправлять запросы (тысячами) и получать ответы, а обработкой будет заниматься потоки из пула.
Записан
rudireg
Гость
Re: Как организовать многопоточность? Выбор модели
«
Ответ #26 :
Октябрь 27, 2016, 19:20 »
Цитата: Old от Октябрь 27, 2016, 18:36
Цитата: rudireg от Октябрь 27, 2016, 17:49
На мой вгляд, следует отправлять запрос серверу...
Не мудрите зря.
Пусть будет поток, который отправляет запросы и обрабатывает сигнал:
void QNetworkAccessManager::finished(QNetworkReply *reply)
Заметьте, это сигнал у самого менеждера и в параметре он передает указатель на reply.
Как только, ответ получен - он отправляется на обработку одному из воркеров пула потоков.
Одного потока-менеджера хватит и отправлять запросы (тысячами) и получать ответы, а обработкой будет заниматься потоки из пула.
Получается такая сехама (поправте меня если я не прав):
1)
Есть
пул потоков вокеров
(
QThreadPool
)
(В этих нитках формируются сетевые запросы, например GET запрос
http://mail.ru
)
2)
Есть 1
поток-менеджер
, который отвечает за работу с посылкой и приемом сетевых запросов.
(Имено в нем идет работа с QNetworkAccessManager)
Если я правильно понял схему, то
потоки-вокеры
кидают сетевые запросы
потоку-менеджеру
(кидают через очередь наверное)
Записан
Old
Джедай : наставник для всех
Offline
Сообщений: 4350
Re: Как организовать многопоточность? Выбор модели
«
Ответ #27 :
Октябрь 27, 2016, 19:32 »
Поток-менеджер сам отправляет запросы и сам получает ответы, а вот обработка ответов может выполняться в несколько потоков.
Нет смысла параллелить отправку запросов, все равно все сведется к сетевому стеку ядра, который последовательно их отправит в сеть. И ждать ответа в нескольких потоках тоже нет смысла, с этим справиться и один поток, а вот когда ответ пришел и его нужно долго обрабатывать, то пригодятся отдельные потоки.
Записан
rudireg
Гость
Re: Как организовать многопоточность? Выбор модели
«
Ответ #28 :
Октябрь 27, 2016, 20:39 »
Нарисовал схему
Верно ли я понял?
Записан
Old
Джедай : наставник для всех
Offline
Сообщений: 4350
Re: Как организовать многопоточность? Выбор модели
«
Ответ #29 :
Октябрь 27, 2016, 20:52 »
В одном потоке живет объект QNetworkAccessManagerа, через него отправляются 1000 запросов, дальше он начинает ждать ответы... Вот пришел первый ответ - отдали его на обработку воркеру, пришел второй ответ - еще одному воркеру, и т.д.
Нет нужды отправлять запросы и пулить ответы в нескольких потоках, ждать легко может только один поток - дело не хитрое.
Записан
Страниц:
1
[
2
]
3
Вверх
Печать
« предыдущая тема
следующая тема »
Перейти в:
Пожалуйста, выберите назначение:
-----------------------------
Qt
-----------------------------
=> Вопросы новичков
=> Уроки и статьи
=> Установка, сборка, отладка, тестирование
=> Общие вопросы
=> Пользовательский интерфейс (GUI)
=> Qt Quick
=> Model-View (MV)
=> Базы данных
=> Работа с сетью
=> Многопоточное программирование, процессы
=> Мультимедиа
=> 2D и 3D графика
=> OpenGL
=> Печать
=> Интернационализация, локализация
=> QSS
=> XML
=> Qt Script, QtWebKit
=> ActiveX
=> Qt Embedded
=> Дополнительные компоненты
=> Кладовая готовых решений
=> Вклад сообщества в Qt
=> Qt-инструментарий
-----------------------------
Программирование
-----------------------------
=> Общий
=> С/C++
=> Python
=> Алгоритмы
=> Базы данных
=> Разработка игр
-----------------------------
Компиляторы и платформы
-----------------------------
=> Linux
=> Windows
=> Mac OS X
=> Компиляторы
===> Visual C++
-----------------------------
Разное
-----------------------------
=> Новости
===> Новости Qt сообщества
===> Новости IT сферы
=> Говорилка
=> Юмор
=> Объявления
Загружается...