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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: Интенсивный обмен данными  (Прочитано 6818 раз)
0...-5
Гость
« : Октябрь 08, 2010, 18:05 »

Здравствуйте! Ситуация такая: есть главный поток обрабатывающий данные и поток их генерирующий, соединенные через сигнал-слот. При интенсивной генерации данных (скажем, на каждом шагу бесконечного цикла без задержек) приложение начинает захлебываться и зависает. Если же в теле цикла выставить задержку (например usleep(1)), то ничего такого не происходит, однако интенсивность обмена данными оставляет желать лучшего. В книге Бланшета написано следующее:
Цитировать
Главный поток может запускать новые потоки, создавая объекты подкласса QThread, как мы это делали в предыдущем разделе. Если эти новые потоки должны взаимодействовать друг с другом, они могут совместно использовать переменные под управлением мьютексов, блокировок чтения/записи, семафоров или специальных событий. Но ни один из этих методов нельзя использовать для связи с главным потоком, поскольку они будут блокировать цикл обработки событий и «заморозят» интерфейс пользователя.
Для связи вторичного потока с главным потоком необходимо использовать межпоточные соединения сигнал-слот.
Есть ли возможность организовать интенсивный обмен данными между главным и дополнительным потоками?
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #1 : Октябрь 08, 2010, 18:34 »

Книги этой я не читал (как впрочем и др. книг) но, судя по Вашей цитате, написано там все правильно. Обычно главная нитка держит UI и контролирует др. нитки (напр может их остановить/прервать). То есть "менеджер", который в основном спит. Если же Вы поручаете ей черновую работу (обработку) - ну то и получаете что рассказали. Нужно перепланировать, соображения такие:

- чего это нитка только получает задания и отфутболивает их главной? Нет ли возможности организовать обработку в той же нитке, а главной только сообщать "столько-то сделано"?

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

- слово "интенсивный" само по себе ни о чем не говорит: частота обмена 10 раз в секунду или в миллисекунду? Если в милли - надо избавляться от сигналов.
Записан
0...-5
Гость
« Ответ #2 : Октябрь 08, 2010, 18:43 »

Хм...попробую описать более конкретно: есть dll-ая библиотека, организующая обмен данными между приложениями. Одно приложение записывает точки, по одной в 4 мс (кажется, Windows гарантирует именно такое время отклика). Мне же нужно соответственно организовать прием этих данных. Вот и приходится в одном потоке ставить бесконечный цикл, в котором ожидаются данные, а при их получении посылать сигнал основному потоку. Основной поток занимается отрисовкой точек.
Использовать другие средства обмена нельзя - стандарт предприятия. Поясните пожалуйста насчет "избавляться от сигналов"
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #3 : Октябрь 08, 2010, 18:58 »

Хм...попробую описать более конкретно: есть dll-ая библиотека, организующая обмен данными между приложениями. Одно приложение записывает точки, по одной в 4 мс (кажется, Windows гарантирует именно такое время отклика). Мне же нужно соответственно организовать прием этих данных. Вот и приходится в одном потоке ставить бесконечный цикл, в котором ожидаются данные, а при их получении посылать сигнал основному потоку. Основной поток занимается отрисовкой точек.
Использовать другие средства обмена нельзя - стандарт предприятия. Поясните пожалуйста насчет "избавляться от сигналов"
Сигналы между нитками сводятся к обмену через eventLoop, а он скоростью не блещет. Заодно надо проверить а действительно ли происходит отсылка в др. нитку (просто здесь легко ошибиться). Ну и конечно, точки должны посылаться "пакетами", слишком жирно вызывать отрисовку для каждой пришедшей. Может быть вообще не заниматься посылкой, а просто рабочая нитка складывает пришедшие точки в контейнер, а главная (с какой-то разумной частотой) их оттуда вынимает. Придется защитить запись/чтение в контейнер но это решает проблемы со скоростью.
Записан
0...-5
Гость
« Ответ #4 : Октябрь 08, 2010, 19:13 »

Хм...дело в том, что тут как бы каждая точка на счету...Т.е. их нельзя копить, а надо сразу обрабатывать, отрисовка это лишь работа основного потока по визуализации...И как в таком случае заменить сигнал-слоты? Если нельзя использовать семафоры и мьютексы для синхронизации основного и неосновного потоков?
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #5 : Октябрь 08, 2010, 19:33 »

Хм...дело в том, что тут как бы каждая точка на счету...Т.е. их нельзя копить, а надо сразу обрабатывать, отрисовка это лишь работа основного потока по визуализации...И как в таком случае заменить сигнал-слоты? Если нельзя использовать семафоры и мьютексы для синхронизации основного и неосновного потоков?
Ну если предприятие принимает такой стандарт (немедленно рисовать каждую  точку, не использовать семафоры и мьютексы  и.т.п) - то такое предприятие должно быть готово к возможным последствиям  Улыбающийся Лучшее что можно сделать - вынести "обработку" (не знаю в чем она заключается) из главной нитки - но это все.
Записан
0...-5
Гость
« Ответ #6 : Октябрь 08, 2010, 19:55 »

Да дело не в стандартах и мьютексы с семафорами никто не запрещает использовать, так всего лишь в книге написано было...Просто это радиолокация и буферизация точек здесь не совсем уместна...
Записан
mad Mr F.
Гость
« Ответ #7 : Октябрь 08, 2010, 20:30 »

В главном потоке в бесконечном цикле можно читать точки из любого места. Со всеми семафорами и мьютексами. Чтоб гуй не тормозил можно в конце каждого шага цикла вызывать processEvents. Но это жуткие костыли. И, как мне кажется, если до этого доходит то где-то раньше в логике напартачили. И не важно радиолокация это или нет. Если у вас, как вы писали, рисуется точка раз в 4 мс. То рисуя пачками по, например, 10 вы получите обновление картинки раз в 40 мс, не думаю что человеческий глаз заметит разницу, а кол-во сигналов вы уменьшите прилично.
Временные задержки критичны при работе с железом, для человека это не так важно. Я не знаю сколько человек успевает увидеть, но много работал с речью и радиосвязью. Для речи задержки до 100мс не критичны, человек их просто не замечает. Так что буферизация вполне себе допустима.
« Последнее редактирование: Октябрь 08, 2010, 20:37 от mad Mr F. » Записан
0...-5
Гость
« Ответ #8 : Октябрь 08, 2010, 22:10 »

Да дело не совсем в отрисовке, я писал же! Алгоритмы должны ловить точки на лету, т.е. по принципу "получил - обработал - мгновенно выдал результат". Допустим, что отрисовкой занимается главный поток, от этого никуда не деться...И здесь, пожалуй, буферизация более, чем уместна! Скажите лучше как наиболее эффективно синхронизировать рабочие потоки...
Записан
mad Mr F.
Гость
« Ответ #9 : Октябрь 08, 2010, 22:17 »

Классы QMutex, QReadWriteLock, QSemaphore, QWaitCondition и глава справки про поддержку потоков Qt. Читайте, выбирайте)
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #10 : Октябрь 09, 2010, 11:33 »

Да дело не совсем в отрисовке, я писал же! Алгоритмы должны ловить точки на лету, т.е. по принципу "получил - обработал - мгновенно выдал результат". Допустим, что отрисовкой занимается главный поток, от этого никуда не деться...И здесь, пожалуй, буферизация более, чем уместна! Скажите лучше как наиболее эффективно синхронизировать рабочие потоки...
Ну это еще туда-сюда (хоть что-то можно  Улыбающийся). Самый простенький вариант - получил, обработал и результат положил в контейнер (для главной нитки). Примитив синхронизации QReadWriteLock. Более сложный путь: получил и поместил во входной контейнер. N др. ниток занимаются выемкой, обработкой и опять-таки складывают результаты в выходной контейнер для главной нитки. Так больше забот зато все ядра задействованы.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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