Russian Qt Forum
Ноябрь 22, 2024, 20:56
Добро пожаловать,
Гость
. Пожалуйста,
войдите
или
зарегистрируйтесь
.
Вам не пришло
письмо с кодом активации?
1 час
1 день
1 неделя
1 месяц
Навсегда
Войти
Начало
Форум
WIKI (Вики)
FAQ
Помощь
Поиск
Войти
Регистрация
Russian Qt Forum
>
Forum
>
Qt
>
Многопоточное программирование, процессы
>
Интенсивный обмен данными
Страниц: [
1
]
Вниз
« предыдущая тема
следующая тема »
Печать
Автор
Тема: Интенсивный обмен данными (Прочитано 6818 раз)
0...-5
Гость
Интенсивный обмен данными
«
:
Октябрь 08, 2010, 18:05 »
Здравствуйте! Ситуация такая: есть главный поток обрабатывающий данные и поток их генерирующий, соединенные через сигнал-слот. При интенсивной генерации данных (скажем, на каждом шагу бесконечного цикла без задержек) приложение начинает захлебываться и зависает. Если же в теле цикла выставить задержку (например usleep(1)), то ничего такого не происходит, однако интенсивность обмена данными оставляет желать лучшего. В книге Бланшета написано следующее:
Цитировать
Главный поток может запускать новые потоки, создавая объекты подкласса QThread, как мы это делали в предыдущем разделе. Если эти новые потоки должны взаимодействовать друг с другом, они могут совместно использовать переменные под управлением мьютексов, блокировок чтения/записи, семафоров или специальных событий. Но ни один из этих методов нельзя использовать для связи с главным потоком, поскольку они будут блокировать цикл обработки событий и «заморозят» интерфейс пользователя.
Для связи вторичного потока с главным потоком необходимо использовать межпоточные соединения сигнал-слот.
Есть ли возможность организовать интенсивный обмен данными между главным и дополнительным потоками?
Записан
Igors
Джедай : наставник для всех
Offline
Сообщений: 11445
Re: Интенсивный обмен данными
«
Ответ #1 :
Октябрь 08, 2010, 18:34 »
Книги этой я не читал (как впрочем и др. книг) но, судя по Вашей цитате, написано там все правильно. Обычно главная нитка держит UI и контролирует др. нитки (напр может их остановить/прервать). То есть "менеджер", который в основном спит. Если же Вы поручаете ей черновую работу (обработку) - ну то и получаете что рассказали. Нужно перепланировать, соображения такие:
- чего это нитка только получает задания и отфутболивает их главной? Нет ли возможности организовать обработку в той же нитке, а главной только сообщать "столько-то сделано"?
- если нет такой возможности, надо заводить 1 или более ниток которые будут заниматься собственно обработкой. В любом случае под контролем главной нитки.
- слово "интенсивный" само по себе ни о чем не говорит: частота обмена 10 раз в секунду или в миллисекунду? Если в милли - надо избавляться от сигналов.
Записан
0...-5
Гость
Re: Интенсивный обмен данными
«
Ответ #2 :
Октябрь 08, 2010, 18:43 »
Хм...попробую описать более конкретно: есть dll-ая библиотека, организующая обмен данными между приложениями. Одно приложение записывает точки, по одной в 4 мс (кажется, Windows гарантирует именно такое время отклика). Мне же нужно соответственно организовать прием этих данных. Вот и приходится в одном потоке ставить бесконечный цикл, в котором ожидаются данные, а при их получении посылать сигнал основному потоку. Основной поток занимается отрисовкой точек.
Использовать другие средства обмена нельзя - стандарт предприятия. Поясните пожалуйста насчет "избавляться от сигналов"
Записан
Igors
Джедай : наставник для всех
Offline
Сообщений: 11445
Re: Интенсивный обмен данными
«
Ответ #3 :
Октябрь 08, 2010, 18:58 »
Цитата: 0...-5 от Октябрь 08, 2010, 18:43
Хм...попробую описать более конкретно: есть dll-ая библиотека, организующая обмен данными между приложениями. Одно приложение записывает точки, по одной в 4 мс (кажется, Windows гарантирует именно такое время отклика). Мне же нужно соответственно организовать прием этих данных. Вот и приходится в одном потоке ставить бесконечный цикл, в котором ожидаются данные, а при их получении посылать сигнал основному потоку. Основной поток занимается отрисовкой точек.
Использовать другие средства обмена нельзя - стандарт предприятия. Поясните пожалуйста насчет "избавляться от сигналов"
Сигналы между нитками сводятся к обмену через eventLoop, а он скоростью не блещет. Заодно надо проверить а действительно ли происходит отсылка в др. нитку (просто здесь легко ошибиться). Ну и конечно, точки должны посылаться "пакетами", слишком жирно вызывать отрисовку для каждой пришедшей. Может быть вообще не заниматься посылкой, а просто рабочая нитка складывает пришедшие точки в контейнер, а главная (с какой-то разумной частотой) их оттуда вынимает. Придется защитить запись/чтение в контейнер но это решает проблемы со скоростью.
Записан
0...-5
Гость
Re: Интенсивный обмен данными
«
Ответ #4 :
Октябрь 08, 2010, 19:13 »
Хм...дело в том, что тут как бы каждая точка на счету...Т.е. их нельзя копить, а надо сразу обрабатывать, отрисовка это лишь работа основного потока по визуализации...И как в таком случае заменить сигнал-слоты? Если нельзя использовать семафоры и мьютексы для синхронизации основного и неосновного потоков?
Записан
Igors
Джедай : наставник для всех
Offline
Сообщений: 11445
Re: Интенсивный обмен данными
«
Ответ #5 :
Октябрь 08, 2010, 19:33 »
Цитата: 0...-5 от Октябрь 08, 2010, 19:13
Хм...дело в том, что тут как бы каждая точка на счету...Т.е. их нельзя копить, а надо сразу обрабатывать, отрисовка это лишь работа основного потока по визуализации...И как в таком случае заменить сигнал-слоты? Если нельзя использовать семафоры и мьютексы для синхронизации основного и неосновного потоков?
Ну если предприятие принимает такой стандарт (немедленно рисовать
каждую
точку, не использовать семафоры и мьютексы и.т.п) - то такое предприятие должно быть готово к возможным последствиям
Лучшее что можно сделать - вынести "обработку" (не знаю в чем она заключается) из главной нитки - но это все.
Записан
0...-5
Гость
Re: Интенсивный обмен данными
«
Ответ #6 :
Октябрь 08, 2010, 19:55 »
Да дело не в стандартах и мьютексы с семафорами никто не запрещает использовать, так всего лишь в книге написано было...Просто это радиолокация и буферизация точек здесь не совсем уместна...
Записан
mad Mr F.
Гость
Re: Интенсивный обмен данными
«
Ответ #7 :
Октябрь 08, 2010, 20:30 »
В главном потоке в бесконечном цикле можно читать точки из любого места. Со всеми семафорами и мьютексами. Чтоб гуй не тормозил можно в конце каждого шага цикла вызывать processEvents. Но это жуткие костыли. И, как мне кажется, если до этого доходит то где-то раньше в логике напартачили. И не важно радиолокация это или нет. Если у вас, как вы писали, рисуется точка раз в 4 мс. То рисуя пачками по, например, 10 вы получите обновление картинки раз в 40 мс, не думаю что человеческий глаз заметит разницу, а кол-во сигналов вы уменьшите прилично.
Временные задержки критичны при работе с железом, для человека это не так важно. Я не знаю сколько человек успевает увидеть, но много работал с речью и радиосвязью. Для речи задержки до 100мс не критичны, человек их просто не замечает. Так что буферизация вполне себе допустима.
«
Последнее редактирование: Октябрь 08, 2010, 20:37 от mad Mr F.
»
Записан
0...-5
Гость
Re: Интенсивный обмен данными
«
Ответ #8 :
Октябрь 08, 2010, 22:10 »
Да дело не совсем в отрисовке, я писал же! Алгоритмы должны ловить точки на лету, т.е. по принципу "получил - обработал - мгновенно выдал результат". Допустим, что отрисовкой занимается главный поток, от этого никуда не деться...И здесь, пожалуй, буферизация более, чем уместна! Скажите лучше как наиболее эффективно синхронизировать рабочие потоки...
Записан
mad Mr F.
Гость
Re: Интенсивный обмен данными
«
Ответ #9 :
Октябрь 08, 2010, 22:17 »
Классы QMutex, QReadWriteLock, QSemaphore, QWaitCondition и глава справки про поддержку потоков Qt. Читайте, выбирайте)
Записан
Igors
Джедай : наставник для всех
Offline
Сообщений: 11445
Re: Интенсивный обмен данными
«
Ответ #10 :
Октябрь 09, 2010, 11:33 »
Цитата: 0...-5 от Октябрь 08, 2010, 22:10
Да дело не совсем в отрисовке, я писал же! Алгоритмы должны ловить точки на лету, т.е. по принципу "получил - обработал - мгновенно выдал результат". Допустим, что отрисовкой занимается главный поток, от этого никуда не деться...И здесь, пожалуй, буферизация более, чем уместна! Скажите лучше как наиболее эффективно синхронизировать рабочие потоки...
Ну это еще туда-сюда (хоть что-то можно
). Самый простенький вариант - получил, обработал и результат положил в контейнер (для главной нитки). Примитив синхронизации QReadWriteLock. Более сложный путь: получил и поместил во входной контейнер. N др. ниток занимаются выемкой, обработкой и опять-таки складывают результаты в выходной контейнер для главной нитки. Так больше забот зато все ядра задействованы.
Записан
Страниц: [
1
]
Вверх
Печать
« предыдущая тема
следующая тема »
Перейти в:
Пожалуйста, выберите назначение:
-----------------------------
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 сферы
=> Говорилка
=> Юмор
=> Объявления
Загружается...