![]() |
Здравствуйте, гость ( Вход | Регистрация )
![]() |
bo0blik |
![]()
Сообщение
#1
|
Студент ![]() Группа: Участник Сообщений: 27 Регистрация: 13.9.2009 Пользователь №: 1089 Спасибо сказали: 0 раз(а) Репутация: ![]() ![]() ![]() |
Буду рад если кто-то поделится исходниками на эту тему, очень интересно посмотреть.
|
|
|
![]() |
ViGOur |
![]()
Сообщение
#2
|
![]() Мастер ![]() ![]() ![]() ![]() ![]() ![]() Группа: Модератор Сообщений: 3296 Регистрация: 9.10.2007 Из: Москва Пользователь №: 4 Спасибо сказали: 231 раз(а) Репутация: ![]() ![]() ![]() |
А что именно интересует?
В том, чтобы самому писать, ничего сложного нет! ![]() |
|
|
bo0blik |
![]()
Сообщение
#3
|
Студент ![]() Группа: Участник Сообщений: 27 Регистрация: 13.9.2009 Пользователь №: 1089 Спасибо сказали: 0 раз(а) Репутация: ![]() ![]() ![]() |
Я просто из тех людей которые пока не увидят код, ничего не поймут.
Просто интересует распределенная много-поточная отправка http запросов. |
|
|
Elfinit |
![]()
Сообщение
#4
|
Участник ![]() ![]() Группа: Участник Сообщений: 127 Регистрация: 17.3.2009 Из: Казань Пользователь №: 619 Спасибо сказали: 7 раз(а) Репутация: ![]() ![]() ![]() |
Вот примерчик. Набор классов для выполнения разных типов запросов с разными параметрами. Примеры использования:
GET:
POST:
Заботиться больше ни о чём (в т.ч. об удалении экзепляров) не нужно, в принципе, даже ответ обрабатывать необязательно, т.е. можно сразу после создания объекта вызывать run. Естественно, обработка любого числа запросов будет происходить параллельно. Плюс имеются сигналы разные (download/upload progress, errors, etc.). И пустые слоты, которые можно заполнить на свой вкус) И ещё - НЕ используй QHttp. Мои классы написаны на основе QNetworkAccessManager Сообщение отредактировал Elfinit - 1.10.2009, 21:58
Прикрепленные файлы
|
|
|
bo0blik |
![]()
Сообщение
#5
|
Студент ![]() Группа: Участник Сообщений: 27 Регистрация: 13.9.2009 Пользователь №: 1089 Спасибо сказали: 0 раз(а) Репутация: ![]() ![]() ![]() |
Elfinit, спасибо большое, про http я уже досконально изучил, просто интересно как это правильней всего с потоками выглядит.
Я посмотрел класс, очень интересный пример. Если у кого еще есть что-нибудь буду очень благодарен. |
|
|
Elfinit |
![]()
Сообщение
#6
|
Участник ![]() ![]() Группа: Участник Сообщений: 127 Регистрация: 17.3.2009 Из: Казань Пользователь №: 619 Спасибо сказали: 7 раз(а) Репутация: ![]() ![]() ![]() |
Elfinit, спасибо большое, про http я уже досконально изучил, просто интересно как это правильней всего с потоками выглядит. Я посмотрел класс, очень интересный пример. Если у кого еще есть что-нибудь буду очень благодарен. Ммм...А зачем вообще париться с потоками в данном случае, за тебя всё библиотека сделает..Главное-инициировать запрос и в нужное время отреагировать на ответ.. |
|
|
rnd |
![]()
Сообщение
#7
|
Студент ![]() Группа: Участник Сообщений: 54 Регистрация: 22.7.2009 Пользователь №: 930 Спасибо сказали: 1 раз(а) Репутация: ![]() ![]() ![]() |
сегодня тоже провозился пол-дня. Пытался сделать из асинхронного режима запросов синхронный, для чего пускал qttp в отдельном потоке - так и не удалось победить - вешается зараза в WaitForMultipleObjects
|
|
|
BRE |
![]()
Сообщение
#8
|
![]() Профессионал ![]() ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 1112 Регистрация: 6.3.2009 Из: Ростов-на-Дону Пользователь №: 591 Спасибо сказали: 264 раз(а) Репутация: ![]() ![]() ![]() |
сегодня тоже провозился пол-дня. Пытался сделать из асинхронного режима запросов синхронный, для чего пускал qttp в отдельном потоке - так и не удалось победить - вешается зараза в WaitForMultipleObjects Как-то связи синхронного режима с отдельным потоком не понял? Вот набросок кода, думаю идея должна быть понятна:
|
|
|
BRE |
![]()
Сообщение
#9
|
![]() Профессионал ![]() ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 1112 Регистрация: 6.3.2009 Из: Ростов-на-Дону Пользователь №: 591 Спасибо сказали: 264 раз(а) Репутация: ![]() ![]() ![]() |
Для того, что бы сделать работу QHttp синхронной, нужно что бы отрабатывали QSocketNotifier. Для этого нужно крутить eventloop (именно там происходят необходимые действия). Предыдущий пример показывал саму идею, "боевой" код я бы сделал примерно таким:
Если необходимо сделать отдельный поток, который делает запрос и получает/обрабатывает ответ, то такой код можно использовать и в методе run потока. |
|
|
rnd |
![]()
Сообщение
#10
|
Студент ![]() Группа: Участник Сообщений: 54 Регистрация: 22.7.2009 Пользователь №: 930 Спасибо сказали: 1 раз(а) Репутация: ![]() ![]() ![]() |
BRE, то, что вы предлагаете - очень опасная практика. Начнут прокачиваться сообщения, т.е. вызываться слоты\обработчики, которые в данный момент времени (посреди работы функции) вызываться совершенно не должны.
Именно поэтому и создается отдельный поток, в который засовывается(moveToThread) объект QNetworkAccessManager там для него и идет прокачка сообщений, а вызывающий поток ждет. Вчерашняя проблема решилась заменой QHttp на QNetworkAccessManager:) |
|
|
BRE |
![]()
Сообщение
#11
|
![]() Профессионал ![]() ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 1112 Регистрация: 6.3.2009 Из: Ростов-на-Дону Пользователь №: 591 Спасибо сказали: 264 раз(а) Репутация: ![]() ![]() ![]() |
BRE, то, что вы предлагаете - очень опасная практика. Начнут прокачиваться сообщения, т.е. вызываться слоты\обработчики, которые в данный момент времени (посреди работы функции) вызываться совершенно не должны. Как ты себе это представляешь? Какие не нужные слоты начнут отрабатывать посреди работы этой функции. Можно по-подробней. Желательно с примерами. Если этот код будет выполняться в отдельном потоке, то и очередь сообщений будет использоваться этого потока. Кстати, не имеет значения что использовать QHttp или QNetworkAccessManager. Сообщение отредактировал BRE - 7.10.2009, 13:06 |
|
|
rnd |
![]()
Сообщение
#12
|
Студент ![]() Группа: Участник Сообщений: 54 Регистрация: 22.7.2009 Пользователь №: 930 Спасибо сказали: 1 раз(а) Репутация: ![]() ![]() ![]() |
Как ты себе это представляешь? Какие не нужные слоты начнут отрабатывать посреди работы этой функции. Можно по-подробней. Желательно с примерами. В смысле какие слоты? Обычные слоты, естественно emit которым был сделан из другого потока. Да и вообще, начнут вызываться все обработки - неважно слот, метаколл или эвент. Если пример еще нужен - могу привести. Кстати, не имеет значения что использовать QHttp или QNetworkAccessManager. Как оказалось - имеет, QNetworkAccessManager не виснет в WaitForMultipleObject, почему различия - выяснять не стал |
|
|
BRE |
![]()
Сообщение
#13
|
![]() Профессионал ![]() ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 1112 Регистрация: 6.3.2009 Из: Ростов-на-Дону Пользователь №: 591 Спасибо сказали: 264 раз(а) Репутация: ![]() ![]() ![]() |
В смысле какие слоты? Обычные слоты, естественно emit которым был сделан из другого потока. Да и вообще, начнут вызываться все обработки - неважно слот, метаколл или эвент. Если пример еще нужен - могу привести. Конечно нужны примеры. Какие ненужные слоты начнут выполняться? По-подробней. выяснять не стал Зря, что не стал. Ты считаешь, что при таком коде ненужные слоты вызываться не будут:
а при таком будут?
|
|
|
rnd |
![]()
Сообщение
#14
|
Студент ![]() Группа: Участник Сообщений: 54 Регистрация: 22.7.2009 Пользователь №: 930 Спасибо сказали: 1 раз(а) Репутация: ![]() ![]() ![]() |
Ну смотри, допустим в очереди лежит два сообщения - на вызов Class1::slot1 и Class1::slot2. Вызывается slot1() - объект переходит в несогласованное состояние. Начинаем прокачку сообщений - сразу вызыватеся slot2, т.е. колл-стек такой:
---------------- slot2() ... slot1() ... ----------------- Поскольку объект в несогласованном состоянии (выполнение slot1 еще не закончилось) - ахтунг! Зря, что не стал. За это не платят:) |
|
|
BRE |
![]()
Сообщение
#15
|
![]() Профессионал ![]() ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 1112 Регистрация: 6.3.2009 Из: Ростов-на-Дону Пользователь №: 591 Спасибо сказали: 264 раз(а) Репутация: ![]() ![]() ![]() |
Ну смотри, допустим в очереди лежит два сообщения - на вызов Class1::slot1 и Class1::slot2. Вызывается slot1() - объект переходит в несогласованное состояние. Начинаем прокачку сообщений - сразу вызыватеся slot2, т.е. колл-стек такой: Мне лучше на примере кода показать. Откуда взялись сообщения, кто их туда положил? Вообще, как ты себе все это представляешь. Продублирую сообщение. Вот примерный код двух разных потоков. Что бы разговор был более предметным. Ты считаешь, что при таком коде ненужные слоты вызываться не будут:
а при таком будут?
Где и какие ненужные сообщения/сигналы/слоты будут вызываться? Сообщение отредактировал BRE - 7.10.2009, 13:37 |
|
|
rnd |
![]()
Сообщение
#16
|
Студент ![]() Группа: Участник Сообщений: 54 Регистрация: 22.7.2009 Пользователь №: 930 Спасибо сказали: 1 раз(а) Репутация: ![]() ![]() ![]() |
Давай отвлечемся от QNetworkAccessNanager - он тут совершенно не при чем сейчас
Смотри, есть два потока, в первом крутится obj1, во втором obj2: Thr1 | Thr2 ------ ------ Obj1 | Obj2 Первый поток эмитит два сигнала sig1, sig2 объекту, который находится во втором потоке. Obj1 ->sig1->Obj2 Obj1 ->sig2->Obj2 Соответствующие слоты(slot1, slot2) не вызываются напрямую, а в очередь Thr2 кладутся сообщения для вызова этих слотов. Дальше, Thr2 извлекает очередное сообщение, видит что это вызов слота slot1 - и вызывает его. Объект Obj2 переходит в несогласованное состояние. Внутри слота slot1 мы начинаем прокачивать сообщения (loop.exec()), Thr2 извлекает следующие сообщение из очереди - видит что это вызов слота slot2 и дергает его - опа приехали, еще не выйдя из slot1 уже запустили slot2! Callstack: ---------- slot2() ..... slot1() .... ------------ Естественно, вместо вызова слотов могут быть любые обработчики. Для того чтобы решить эту проблему - и создается дополнительный поток - Thr3. В него помещается объект и сообщения этот объект получает в нем. А вызывающие поток ждет окончания Thr3 НЕ прокачивая при этом свои сообщения. |
|
|
BRE |
![]()
Сообщение
#17
|
![]() Профессионал ![]() ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 1112 Регистрация: 6.3.2009 Из: Ростов-на-Дону Пользователь №: 591 Спасибо сказали: 264 раз(а) Репутация: ![]() ![]() ![]() |
Тебе не кажется, что это немного надуманный пример.
Я привел тебе код, который будет работать в потоке синхронно. Если существует возможность такой ситуации, о которой пишешь ты, то такие случаи нужно учитывать отдельно (например использовать Qt::BlockingQueuedConnection), а лучше так никогда не делать. А прокрутка очереди сообщений, это вовсе не опасная практика. Она повсеместно используется в Qt: от оживления длительных операций и до модальных диалогов. Главное думать, что делаешь. Сообщение отредактировал BRE - 8.10.2009, 8:17 |
|
|
rnd |
![]()
Сообщение
#18
|
Студент ![]() Группа: Участник Сообщений: 54 Регистрация: 22.7.2009 Пользователь №: 930 Спасибо сказали: 1 раз(а) Репутация: ![]() ![]() ![]() |
Надуманный?
![]() Это крайне упрощенный пример. Мне сложно представить многопоточное приложение, использующие очереди, в котором несанкционированная прокачка сообщений не будет проблемой. На эти грабли наступали уже не раз. Приложение, над которым сейчас работаем активно использует пул потоков, пересылку сообщений между ними и минимум синхронизаций. Использование прокачки сообщений в коде - запрещено. Кстати модальные диалоги - тоже не айс, именно по этой причине. Я не говорю, что это должна быть запрещенная практика, просто многие люди не задумываются, что реально происходит при таком подходе. И каждое использование прокачки сообщений должно быть обдумано несколько раз, со всеми возможными последствиями. |
|
|
BRE |
![]()
Сообщение
#19
|
![]() Профессионал ![]() ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 1112 Регистрация: 6.3.2009 Из: Ростов-на-Дону Пользователь №: 591 Спасибо сказали: 264 раз(а) Репутация: ![]() ![]() ![]() |
Мне сложно представить многопоточное приложение, использующие очереди, в котором несанкционированная прокачка сообщений не будет проблемой. На эти грабли наступали уже не раз. Приложение, над которым сейчас работаем активно использует пул потоков, пересылку сообщений между ними и минимум синхронизаций. Использование прокачки сообщений в коде - запрещено. Такие ситуации возникают тогда, когда нитка запущена и в пустую крутит цикл обработки сообщений, ожидая прихода внешнего события. После чего в своем контексте выполняет необходимый код. К тому же у вас в контексте этой нити можно выполнять разный код (в зависимости от слота). Вопрос: для чего эта нить висит и ждет этого события? Наверное лучше в нужный момент запустить нить, которая выполнит необходимое действие и завершиться. А если нужны сложности, конечно можно ограничивать себя по "самые помидоры" и держать активную нить, которая будут пытаться в своем контексте выполнять множество разных действия. ![]() ![]() Я не говорю, что это должна быть запрещенная практика, просто многие люди не задумываются, что реально происходит при таком подходе. И каждое использование прокачки сообщений должно быть обдумано несколько раз, со всеми возможными последствиями. +мульон |
|
|
![]() ![]() ![]() |
![]() |
|
Текстовая версия | Сейчас: 7.6.2025, 16:23 |